分片(partitioning)就是将你的数据拆分到多个 Redis 实例的过程,这样每个实例将只包含所有键的子集.(相关推荐:Redis教程)
1 分片何用
Redis 的分片承担着两个主要目标:
• 允许使用很多电脑的内存总和来支持更大的数据库。没有分片,你就被局限于单机能支持的内存容量。
• 允许伸缩计算能力到多核或多服务器,伸缩网络带宽到多服务器或多网络适配器。
2 分片基础
有很多不同的分片标准(criteria).
假想我们有 4 个 Redis 实例 R0,R1,R2,R3,还有很多表示用户的键,像 user:1,user:2,… 等等,我们能找到不同的方式来选择一个指定的键存储在哪个实例中。换句话说,有许多不同的办法来映射一个键到一个指定的 Redis 服务器。
最简单的执行分片的方式之一是范围分片(range partitioning),通过映射对象的范围到指定的 Redis 实例来完成分片。例如,我可以假设用户从 ID 0 到 ID 10000 进入实例 R0,用户从 ID 10001 到 ID 20000 进入实例 R1.
这套办法行得通,并且事实上在实践中被采用,然而,这有一个缺点,就是需要一个映射范围到实例的表格.
这张表需要管理,不同类型的对象都需要一个表,所以范围分片在 Redis 中常常并不可取,因为这要比其他分片可选方案低效得多。
一种范围分片的替代方案是哈希分片(hash partitioning).
本文@来#源gaodai$ma#com搞$$代**码网搞代gaodaima码这种模式适用于任何键,不需要键像 object_name: 这样的饿形式,就像这样简单
• 使用一个哈希函数(例如,crc32 哈希函数) 将键名转换为一个数字。例如,如果键是 foobar,crc32(foobar)将会输出类似于 93024922 的东西。
• 对这个数据进行取模运算,以将其转换为一个 0 到 3 之间的数字,这样这个数字就可以映射到我的 4 台 Redis 实例之一。93024922 模 4 等于 2,所以我知道我的键 foobar 应当存储到 R2 实例。注意:取模操作返回除法操作的余数,在许多编程语言总实现为%操作符。
有许多其他的方式可以分片,从这两个例子中你就可以知道了。一种哈希分片的高级形式称为一致性哈希(consistent hashing),被一些 Redis 客户端和代理实现。
3 分片实现(理论)
分片可由软件栈中的不同部分来承担。
• 客户端分片(Client side partitioning)
客户端直接选择正确的节点来写入和读取指定键,许多 Redis 客户端实现了客户端分片.
• 代理协助分片(Proxy assisted partitioning)
我们的客户端发送请求到一个可以理解 Redis 协议的代理上.而不是直接发送请求到 Redis 实例上.
代理会根据配置好的分片模式,来保证转发我们的请求到正确的 Redis 实例,并返回响应给客户端.
Redis 和 Memcached 的代理 Twemproxy 实现了代理协助的分片.
• 查询路由(Query routing)
你可以发送你的查询到一个随机实例,这个实例会保证转发你的查询到正确的节点.
Redis 集群在客户端的帮助下,实现了查询路由的一种混合形式 (请求不是直接从 Redis 实例转发到另一个,而是客户端收到重定向到正确的节点).
4 分片缺点
Redis 的一些特性与分片在一起时玩的不是很好
• 涉及多个键的操作通常不支持。例如,你不能对映射在两个不同 Redis 实例上的键执行交集(事实上有办法做到,但不是直接这么干).
• 涉及多个键的事务不能使用
• 分片的粒度(granularity)是键,所以不能使用一个很大的键来分片数据集,例如一个很大的有序集合