查看“Redis:管道技术、分区”的源代码
←
Redis:管道技术、分区
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
[[category:Redis]] __TOC__ == 管道技术 == Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。这意味着通常情况下一个请求会遵循以下步骤: # 客户端向服务端发送一个查询请求,并监听 Socket 返回,通常是以“阻塞”模式,等待服务端响应。 # 服务端处理命令,并将结果返回给客户端。 但,Redis 管道技术可以在服务端未响应时,'''客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应'''。 示例,通过使用 PING 命令查看redis服务是否可用,之后设置了 runoobkey 的值为 redis,然后获取 runoobkey 的值并使得 visitor 自增 3 次: <syntaxhighlight lang="java" highlight=""> $(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 </syntaxhighlight> 在返回的结果中我们可以看到这些命令一次性向 redis 服务提交,并'''最终一次性读取所有服务端的响应'''。 综上所述,pipeline 就是把'''一组命令进行打包,然后一次性通过网络发送到 Redis,同时将执行的结果批量的返回回来。'''通过管道技术能够减少的I/O的调用次数。 管道技术最显著的优势是提高了 redis 服务的性能。 : 测试: : <syntaxhighlight lang="java" highlight=""> 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 } </syntaxhighlight> <syntaxhighlight lang="java" highlight=""> without pipelining 1.185238 seconds with pipelining 0.250783 seconds </syntaxhighlight> 如上,开启管道后,速度效率提升了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 实例中。
返回至“
Redis:管道技术、分区
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
笔记
服务器
数据库
后端
前端
工具
《To do list》
日常
阅读
电影
摄影
其他
Software
Windows
WIKIOE
所有分类
所有页面
侧边栏
站点日志
工具
链入页面
相关更改
特殊页面
页面信息