Redis:管道技术、分区
跳到导航
跳到搜索
管道技术
Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。这意味着通常情况下一个请求会遵循以下步骤:
- 客户端向服务端发送一个查询请求,并监听 Socket 返回,通常是以“阻塞”模式,等待服务端响应。
- 服务端处理命令,并将结果返回给客户端。
但,Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。
示例,通过使用 PING 命令查看redis服务是否可用,之后设置了 runoobkey 的值为 redis,然后获取 runoobkey 的值并使得 visitor 自增 3 次:
$(echo -en "PING\r\n SET runoobkey redis\r\nGET runoobkey\r\nINCR visitor\r\nINCR visitor\r\nINCR visitor\r\n"; sleep 10) | nc localhost 6379
+PONG
+OK
redis
:1
:2
:3
在返回的结果中我们可以看到这些命令一次性向 redis 服务提交,并最终一次性读取所有服务端的响应。
综上所述,pipeline 就是把一组命令进行打包,然后一次性通过网络发送到 Redis,同时将执行的结果批量的返回回来。通过管道技术能够减少的I/O的调用次数。
管道技术最显著的优势是提高了 redis 服务的性能。
- 测试:
require 'rubygems' require 'redis' def bench(descr) start = Time.now yield puts "#{descr} #{Time.now-start} seconds" end def without_pipelining r = Redis.new 10000.times { r.ping } end def with_pipelining r = Redis.new r.pipelined { 10000.times { r.ping } } end bench("without pipelining") { without_pipelining } bench("with pipelining") { with_pipelining }
without pipelining 1.185238 seconds
with pipelining 0.250783 seconds
如上,开启管道后,速度效率提升了5倍。
分区
分区就是分割数据到多个Redis实例,每个实例只保存key的一个子集。
优点:
- 通过利用多台计算机内存的和值,允许我们构造更大的数据库。
- 通过多核和多台计算机,允许我们扩展计算能力;通过多台计算机和网络适配器,允许我们扩展网络带宽。
缺点:
- 涉及多个 key 的操作通常不被支持。
- 比如,当两个set映射到不同的redis实例上时,不能对这两个set执行交集操作。
- 涉及多个 key 的 redis 事务不能使用。
- 数据处理较为复杂。
- 比如,需要处理多个rdb/aof文件,并且从多个实例和主机备份持久化文件。
- 增加或删除容量也比较复杂。redis集群大多数支持在运行时增加、删除节点的透明数据平衡的能力,但是类似于客户端分区、代理等其他系统则不支持这项特性。然而,一种叫做presharding的技术对此是有帮助的。
分区类型
Redis 有两种类型分区。
- 假设有 4 个 Redis 实例 R0,R1,R2,R3,和类似 user:1,user:2 这样的表示用户的多个 key,对既定的 key 有多种不同方式来选择这个 key 存放在哪个实例中。
也就是说,有不同的系统来映射某个 key 到某个 Redis 服务。
范围分区
最简单的分区方式是按范围分区,就是映射一定范围的对象到特定的 Redis 实例。
- 比如,ID 从 0 到 10000 的用户会保存到实例 R0,ID 从 10001 到 20000 的用户会保存到 R1,以此类推。
- 这种方式是可行的,并且在实际中使用,不足就是要有一个区间范围到实例的映射表。
- 这个表要被管理,同时还需要各种对象的映射表,通常对 Redis 来说并非是好的方法。
哈希分区
另外一种分区方法是 hash 分区。
这对任何key都适用,也无需是 object_name: 这种形式,像下面描述的一样简单:
- 用一个 hash 函数将 key 转换为一个数字。
- 比如使用 crc32 hash函数。对 key “foobar”执行“crc32(foobar)”会输出类似 93024922 的整数。
- 对这个整数取模,将其转化为 0-3 之间的数字,就可以将这个整数映射到 4 个 Redis 实例中的一个了。
- 93024922 % 4 = 2,就是说 key “foobar”应该被存到 R2 实例中。