Redis 实战 —— 13. 扩展 Redis
简介
当数据量增大或者读写请求增多后,一台 Redis 服务器可能没办法再存储所有数据或者处理所有读写请求,那么就需要对 Redis 进行扩展,保证 Redis 在能存储所有数据对情况下,同时能正常处理读写请求。 P227
扩展读性能 P227
提高性能的几个途径 P228
- 使用短结构:确保压缩列表的最大长度不会太大
- 根据查询类型选择结构
- 不要把列表当作集合使用
- 不要获取整个散列,然后再客户端里面进行排序,而应使用有序集合
- 大体积对象存储前进行压缩:减少读写所需的网络带宽。对比 lz4, gzip 和 bzip2 等压缩算法,选择对存储数据压缩效果和性能最好对压缩算法
- 流水线和连接池:复制、处理故障、事务及性能优化 中介绍过流水线
扩展读性能最简单的方法就是添加只读服务器(复制、处理故障、事务及性能优化 中介绍过通过复制 (replication) 让一个 Redis 服务器成为从服务器及运作原理和管理方法),并只对主服务器进行写入(默认情况下,尝试对一个从服务器进行写入将引发一个错误,即使它是其他从服务器的主服务器)。 P228
添加从服务器 P228
- 在配置文件中加上:
slaveof <master-host> <master-port> - 向正在运行对 Redis 服务器发送:
SLAVEOF <master-host> <master-port>
可以通向从服务器发送 SLAVEOF NO ONE 命令让其与主服务器断开。 P228
当一个主服务器有大量从服务器时,那么它们以前同步时就会耗尽大部分带宽,导致主服务器延迟变高,甚至导致主服务器断开和从服务器的连接。 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
Redis 实战 —— 13. 扩展 Redis的更多相关文章
- Redis实战之征服 Redis + Jedis + Spring (一)
Redis + Jedis + Spring (一)—— 配置&常规操作(GET SET DEL)接着需要快速的调研下基于Spring框架下的Redis操作. 相关链接: Redis实战 Re ...
- Redis实战之征服 Redis + Jedis + Spring (二)
不得不说,用哈希操作来存对象,有点自讨苦吃! 不过,既然吃了苦,也做个记录,也许以后API升级后,能好用些呢?! 或许,是我的理解不对,没有真正的理解哈希表. 相关链接: Redis实战 Redis实 ...
- Redis实战之征服 Redis + Jedis + Spring (三)
一开始以为Spring下操作哈希表,列表,真就是那么土.恍惚间发现“stringRedisTemplate.opsForList()”的强大,抓紧时间恶补下. 通过spring-data-redis完 ...
- Redis实战 | 5种Redis数据类型详解
我们知道Redis是目前非常主流的KV数据库,它因高性能的读写能力而著称,其实还有另外一个优势,就是Redis提供了更加丰富的数据类型,这使得Redis有着更加广泛的使用场景.那Redis提供给用户的 ...
- Redis实战——phpredis扩展安装
准备安装软件(download) 1> [redis] http://redis.googlecode.com/files/redis-2.4.3.tar.gz 2> [php ...
- 小D课堂 - 零基础入门SpringBoot2.X到实战_第9节 SpringBoot2.x整合Redis实战_40、Redis工具类封装讲解和实战
笔记 4.Redis工具类封装讲解和实战 简介:高效开发方式 Redis工具类封装讲解和实战 1.常用客户端 https://redisdesktop.com/download ...
- Redis实战
大约一年多前,公司同事开始使用Redis,不清楚是配置,还是版本的问题,当时的Redis经常在使用一段时间后,连接爆满且不释放.印象中,Redis 2.4.8以下的版本由于设计上的主从库同步问题,就会 ...
- Redis实战篇
Redis实战篇 1 Redis 客户端 1.1 客户端通信 原理 客户端和服务器通过 TCP 连接来进行数据交互, 服务器默认的端口号为 6379 . 客户端和服务器发送的命令或数据一律以 \r\n ...
- Redis实战(一)Redis简介及环境安装(Windows)
提到Redis,大家肯定都听过,并且应该都在项目中或多或少的使用过,也许你觉得Redis用起来挺简单的呀,但如果有人问你下面的几个问题(比如同事或者面试官),你能回答的上来吗? 什么是Redis? R ...
随机推荐
- 神奇的 SQL 之性能优化 → 让 SQL 飞起来
开心一刻 一天,一个男人去未婚妻家玩,晚上临走时下起了大雨 未婚妻劝他留下来过夜,说完便去准备被褥,准备就绪后发现未婚夫不见了 过了好久,全身淋的像只落汤鸡的未婚夫回来了 未婚妻吃惊的问:" ...
- python函数----名称空间和作用域
一 名称空间 名称空间即存放名字与对象映射/绑定关系的地方. 对于x=3,Python会申请内存空间存放对象3,然后将名字x与3的绑定关系存放于名称空间中,del x表示清除该绑定关系. 在程序执行 ...
- python数据基本运算处理===循环
一.循环语句 1.while while的循环条件为True,即每次正常循环完毕都会返回判断一次条件 只有读到break才能立刻彻底结束循环,break只能结束本层循环 continue也能立即结束本 ...
- Redis缓存篇(二)淘汰机制:缓存满了怎么办?
上一讲提到,缓存的容量总是小于后端数据库的.随着业务系统的使用,缓存数据会撑满内存空间,该怎么处理呢? 本节我们来学习内存淘汰机制.在Redis 4.0之前有6种内存淘汰策略,之后又增加2种,一共8种 ...
- js 中const 定义的值是否能更改
const定义的基本类型不能改变,但是定义的对象是可以通过修改对象属性等方法来改变的. 1. const aa=trueaa=falseconsole.log(aa)VM1089:2 Uncaught ...
- 《计算机组成原理 》& 《计算机网络》& 《数据库》 Roadmap for self-taugh student
计算机组成原理: UCB的这门课绝对是不错的资源. Great Ideas in Computer Architecture (Machine Structures) B站:https://www.b ...
- MybatisPlus多数据源及事务解决思路
关于多数据源解决方案 目前在SpringBoot框架基础上多数据源的解决方案大多手动创建多个DataSource,后续方案有三: 继承org.springframework.jdbc.datasour ...
- 目录遍历 - Pikachu
概述: 在web功能设计中,很多时候我们会要将需要访问的文件定义成变量,从而让前端的功能便的更加灵活. 当用户发起一个前端的请求时,便会将请求的这个文件的值(比如文件名称)传递到后台,后台再执行其对应 ...
- cmd的终结工具cmder
常用快捷键 win+alt+t 打开任务设置窗口 win+alt+k 打开快捷键设置窗口 自定义屏幕分割窗口快捷键: ctl+shift+s 水平按50%比例分割 ctl+shift+v 垂直按50 ...
- Pandas的数据分组-aggregate聚合
在对数据进行分组之后,可以对分组后的数据进行聚合处理统计. agg函数,agg的形参是一个函数会对分组后每列都应用这个函数. import pandas as pd import numpy as n ...
