Redis 实战 —— 13. 扩展 Redis

简介

当数据量增大或者读写请求增多后,一台 Redis 服务器可能没办法再存储全部数据或者处理全部读写请求,那么就须要对 Redis 进行扩展,保证 Redis 在能存储全部数据对状况下,同时能正常处理读写请求。 P227git

扩展读性能 P227

提升性能的几个途径 P228
  • 使用短结构:确保压缩列表的最大长度不会太大
  • 根据查询类型选择结构
    • 不要把列表看成集合使用
    • 不要获取整个散列,而后再客户端里面进行排序,而应使用有序集合
  • 大致积对象存储前进行压缩:减小读写所需的网络带宽。对比 lz4, gzip 和 bzip2 等压缩算法,选择对存储数据压缩效果和性能最好对压缩算法
  • 流水线和链接池:复制、处理故障、事务及性能优化 中介绍过流水线

扩展读性能最简单的方法就是添加只读服务器(复制、处理故障、事务及性能优化 中介绍过经过复制 (replication) 让一个 Redis 服务器成为从服务器及运做原理和管理方法),并只对主服务器进行写入(默认状况下,尝试对一个从服务器进行写入将引起一个错误,即便它是其余从服务器的主服务器)。 P228github

添加从服务器 P228
  • 在配置文件中加上: slaveof <master-host> <master-port>
  • 向正在运行对 Redis 服务器发送: SLAVEOF <master-host> <master-port>

能够通向从服务器发送 SLAVEOF NO ONE 命令让其与主服务器断开。 P228redis

当一个主服务器有大量从服务器时,那么它们之前同步时就会耗尽大部分带宽,致使主服务器延迟变高,甚至致使主服务器断开和从服务器的链接。 P229算法

解决从服务器重同步 (resync) 问题的方法 P229数据库

  • 构建树状的从服务器群组:经过构建二级从服务器下降主服务器须要传递给从服务器的数据量
  • 对网络链接进行压缩:使用带压缩带 SSH 隧道 (tunnel) 进行链接能够明显地下降带宽(注意使用 SSH 提供的选项让 SSH 链接在断线后自动链接)
故障转移 P230

Redis Sentinel 能够配合 Redis 的复制功能使用,并对下线的主服务器进行故障转移。 Redis Sentinel 是运行在特殊模式下的 Redis 服务器,它会监视一系列主服务器以及它们的从服务器,经过向主服务器发送 PUBLISH 命令和 SUBSCRIBE 命令,并向主服务器和从服务器发送 PING 命令,各个 Sentinel 进程能够自主识别可用的从服务器和其余 Sentinel 。当主服务器失效时,监视这个主服务器的全部 Sentinel 就会基于彼此共有的信息选出一个 Sentinel ,并从现有的从服务器中选择一个新的主服务器。而后被选中的 Sentinel 就会让剩余的其余从服务器去复制这个新的主服务器(默认设置下, Sentinel 会一个接一个地迁移从服务器,但这个数量能够经过配置选项进行修改)。 P230性能优化

Redis Sentinel 还提供了可选的故障转移通知功能,这个功能能够经过调用用户提供的脚原本执行配置更新等操做。 P230服务器

扩展写性能和内存容量 P230

下降内存占用,减小需写入的数据 P231
  • 减小程序须要读取的数据量
  • 无关功能迁移至其余服务器
  • 写入 Redis 前,尝试内存中进行聚合(能够应用于分析和统计计算)
  • 使用锁或者 Lua 脚本代替 WATCH/MULTI/EXEC 事务
  • 使用 AOF 持久化会将写入的全部数据存储起来,能够考虑配置重写 AOF 或使用 RDB

当使用上述方法没法继续下降内存并提高性能以后,就说明已经遇到了只使用一台机器带来的瓶颈,那么就须要将数据分片到多台机器上面。咱们介绍使用固定分片数量的方法,使得分片方案可以知足将来几年的预期,假设分片为 256 片。那么前期在数据量很是小的状况下不必每一个 Redis 服务器都使用独立的机器,能够多个 Redis 服务器共用一台机器,或者每一个 Redis 服务器使用多个 Redis 数据库。 (注意:每台机器上运行多个 Redis 服务器时,确保监听不一样的端口,并确保服务器写入的都是不一样的快照文件/ AOF 文件。)P231网络

分片方法能够直接采用 下降内存占用 中提到的先使用散列函数计算出一个数字散列值,而后使用分片数量计算出当前采用哪一个链接便可,即再也不对 key 进行分片,而是转换为对链接进行分片。 P234多线程

若是执行复杂查询时,感受性能受到了 Redis 单线程设计的限制,而且机器有更多的计算核心、更多的通讯网络资源,以及更多用于存储快照文件和 AOF 文件的磁盘 I/O ,那么能够考虑在单台机器上面运行多个 Redis 服务器。(固然也须要注意:确保一台机器上的多个 Redis 服务器监听不一样的端口,并确保服务器写入的都是不一样的快照文件/ AOF 文件。) P234并发

所思

若是网络 I/O 成为瓶颈的话,那么也能够考虑 Redis 6.0 的多线程特性。多线程特性主要是改进读写缓冲区的性能,由于这部分时间占比较大,而命令执行部分仍然使用单线程处理。这样既能提升总体性能,又能够保持设计简单,也不会引入新的并发问题。

对于一些全局惟一的数据,例如:惟一访问计数器等,能够额外使用一个链接专门存储相似的数据。

扩展复杂查询 P234
扩展搜索查询量 P235

实现内容搜索、定向广告和职位搜索 中提到的各类搜索方法都使用了相似 SUNIONSTORE, SINTERSTORE, SDIFFSTORE, ZINTERSTORE, ZUNIONSTORE 等命令,而这些命令都须要对 Redis 进行写入,因此前面介绍的只读从服务器将没法处理这些搜索。 P235

为了执行上述搜索,须要开启对从服务器对写入功能。 Redis 对配置文件中, slave-read-only 选项控制可否对从服务器进行写入,默认值为 yes 。因此只要将 slave-read-only 设置为 no 并重启从服务器,上述搜索便可正常执行。 P235

当机器拥有足够多的内存,而且它执行的都是只读操做(或者说这些操做不会修改其余查询所使用的底层数据)的时候,添加从服务器可以帮助咱们实现横向扩展 (scale out) 。

扩展搜索索引大小 P235

为了对搜索查询进行链接分片,咱们必须先对搜索索引进行链接分片,确保对于每一个被索引的文档来讲,同一个文档的全部数据都会被存储到同一个链接分片里面。 P236

分片搜索实际流程大体分为如下三个操做:

  • 编写可以在单个分片上面执行对查询程序,让它进行搜索并获取待排序对搜索结果
  • 在全部分片执行上面提到的查询程序
  • 对各个分片对查询结果进行合并,而后选出想要的那部分结果

注意:因为没法肯定分页结果中的每条数据分别来自哪一个分片,因此为了确保返回的数据在 [start, start + num] 内,程序须要从每一个分片获取 [0, start + num] 内的数据,而后在内存中选出最终结果。 P236

所思

分片其实也就两种形式:

  • 对键进行分片:适用于大量相似键,但每一个键对应的数据量不大的状况
  • 对数据进行分片:适用于每一个键对应对数据量很大的状况

对键进行分片基本和链接分片绑定了,由于大量键只有在多链接对状况下分片才有用;而对数据进行分片既能够在单个链接中变成多个键,也能够转化成链接分片。

本文首发于公众号:满赋诸机(点击查看原文) 开源在 GitHub :reading-notes/redis-in-action

相关文章
相关标签/搜索