网站站外优化怎么做,骏驰网站开发,软件界面设计app,深圳上市公司全部名单六、Redis 分布式系统 —— 超详细操作演示#xff01; 六、Redis 分布式系统6.1 数据分区算法6.1.1 顺序分区6.1.2 哈希分区 6.2 系统搭建与运行6.2.1 系统搭建6.2.2 系统启动与关闭 6.3 集群操作6.3.1 连接集群6.3.2 写入数据6.3.3 集群查询6.3.4 故障转移6.3.5 集群扩容6.3… 六、Redis 分布式系统 —— 超详细操作演示 六、Redis 分布式系统6.1 数据分区算法6.1.1 顺序分区6.1.2 哈希分区 6.2 系统搭建与运行6.2.1 系统搭建6.2.2 系统启动与关闭 6.3 集群操作6.3.1 连接集群6.3.2 写入数据6.3.3 集群查询6.3.4 故障转移6.3.5 集群扩容6.3.6 集群收缩 6.4 分布式系统的限制 数据库系列文章 关系型数据库: MySQL —— 基础语法大全MySQL —— 进阶 非关系型数据库: 一、Redis 的安装与配置二、Redis 基本命令上三、Redis 基本命令下四、Redis 持久化五、Redis 主从集群 六、Redis 分布式系统 Redis 分布式系统官方称为 Redis Cluster Redis 集群其是 Redis 3.0 开始推出的分布式解决方案。其可以很好地解决 不同 Redis 节点 存放不同数据并将用户请求方便地路由到不同 Redis 的问题。
6.1 数据分区算法 分布式数据库系统 会根据不同的数据分区算法将数据分散存储到不同的数据库服务器节点上每个节点管理着整个数据集合中的一个子集。 常见的数据分区规则有两大类顺序分区 与 哈希分区。
6.1.1 顺序分区 顺序分区规则可以将数据按照某种顺序平均分配到不同的节点。 不同的顺序方式产生了不同的分区算法。 例如轮询分区算法、时间片轮转分区算法、数据块分区算法 、业务主题分区算法等。由于这些算法都比较简单所以这里就不展开描述了。
⭐️1轮询分区算法 每产生一个数据就依次分配到不同的节点。该算法适合于数据问题不确定的场景。其分配的结果是在数据总量非常庞大的情况下每个节点中数据是很平均的。但生产者与数据节点间的连接要 长时间保持。
⭐️2时间片轮转分区算法 在某个固定长度的时间片内的数据都会分配到一个节点。时间片结束再产生的数据就会被分配到下一个节点。这些节点会被依次轮转分配数据。该算法可能会出现节点数据 不平均 的情况因为每个时间片内产生的数据量可能是不同的。但生产者与节点间的连接只需占用当前正在使用的这个就可以其它连接使用完毕后就立即释放。
⭐️3数据块分区算法 在整体数据总量确定的情况下根据各个节点的存储能力可以将连接的某一整块数据分配到某一节点。
⭐️4业务主题分区算法 数据可根据不同的业务主题分配到不同的节点。
6.1.2 哈希分区 哈希分区规则是充分利用数据的哈希值来完成分配对 数据哈希值 的 不同使用方式 产生了不同的哈希分区算法。哈希分区算法相对较复杂这里详细介绍几种常见的哈希分区算法。
⭐️1节点取模分区算法 该算法的前提是每个节点 都已分配好了一个唯一序号对于 N 个节点的分布式系统其序号范围为 [0, N - 1] 。然后选取数据本身或可以代表 数据特征 的数据的一部分作为 key 计算 hash(key) 与 节点数量 N 的模该计算结果即为该数据的存储节点的序号。 该算法最大的优点是简单但其也存在较严重的不足。如果分布式系统扩容或缩容已经存储过的数据需要根据新的节点数量 N 进行 数据迁移否则用户根据 key 是无法再找到原来的数据的。 生产中扩容一般采用 翻倍扩容 / 减半缩容 方式以减少扩容时数据迁移的比例。
⭐️2一致性哈希分区算法 一致性 hash 算法通过一个叫作 一致性 hash环 的数据结构实现。这个环的起点是 0 终点是 2 32 − 1 2^{32} - 1 232−1 并且起点与终点重合。 环中间的整数按 逆/顺时针 分布故这个环的整数分布范围是 [0, 2 32 − 1 2^{32} - 1 232−1 ] 。 上图中存在四个对象 o1 、 o2 、 o3 、 o4 分别代表四个待分配的数据红色方块是这四个数据的 hash(o) 在 Hash 环中的落点。同时图上还存在三个节点 m0 、 m1 、 m2 绿色圆圈是这三节点的 hash(m) 在 Hash 环中的落点。 现在要为数据分配其要存储的节点。该数据对象的 hash(o) 按 照逆/顺时针方向距离哪个节点的 hash(m) 最近就将该数据存储在哪个节点。这样就会形成上图所示的分配结果。 该算法的最大优点是节点的扩容与缩容仅对按照逆/顺时针方向距离该节点 最近的节点有影响对其它节点无影响。 当节点数量较少时非常容易形成数据倾斜问题且节点变化影响的节点数量占比较大即影响的数据量较大。所以该方式不适合数据节点较少的场景。
⭐️3虚拟槽分区算法 该算法首先虚拟出一个固定数量的 整数集合该集合中的每个整数称为一个 slot槽。这个槽的数量一般是远远大于节点数量的。然后再将所有 slot 槽 平均映射到各个节点之上。例如 Redis 分布式系统中共虚拟了 16384 个 slot 槽其范围为 [0, 16384]。假设共有 3 个节点那么 slot 槽与节点间的映射关系如下图 所示 而 数据 只与 slot 槽有关系 与节点没有直接关系。 数据只通过其 key 的 hash(key) 映射到 slot 槽 slot hash(key) % slotNums 。这也是该算法的一个优点解耦了数据与节点客户端无需维护节点只需维护与 slot 槽的关系即可。 Redis 数据分区采用的就是该算法。 其计算槽点的公式为 slot CRC16(key) % 16384 。CRC16() 是一种带有校验功能的 、具有良好分散功能的、 特殊的 hash 算法函数。 其实 Redis 中计算槽点的公式不是上面的那个而是 slot CRC16(key) 16383 。 若要计算 a % b 如果 b 是 2 的整数次幂那么 a % b a (b - 1) 。(位运算比数学运算快) 6.2 系统搭建与运行
6.2.1 系统搭建
⭐️1 系统架构 下面要搭建的 Redis 分布式系统由 6 个节点构成这 6 个节点的地址及角色分别如下表所示。一个 master 配备一个 slave 不过 master 与 slave 的配对关系在系统搭建成功后会自动分配。 ⭐️2 删除持久化文件 先将之前“ Redis 主从集群 ”中在 Redis 安装目录下生成的 RDB 持久化文件 dump638*.conf 与 AOF 持久化文件 删除。因为 Redis 分布式系统要求创建在一个空的数据库之上。注意 AOF 持久化文件全部在 appendonlydir 目录中。
rm -rf dump638*.rdb appendonlydir638*.aof⭐️3 创建目录 在Redis 安装目录中 mkdir 一个新的目录 cluster-dis 用作分布式系统的工作目录。
mkdir cluster-dis⭐️4 复制 2 个 配置文件 将 cluster 目录中的 redis.conf 与 redis6380.conf 文件复制到 cluster-dis 目录。
cd cluster-dis/
cp ../cluster/redis.conf ./
cp ../cluster/redis6380.conf ./⭐️5 修改 redis.conf 对于redis.conf 配置文件主要涉及到以下三个四个属性
A、 dir 指定工作目录为前面创建的 cluster-dis 目录。持久化文件、节点配置文件将来都会在工作目录中自动生成。 命令模型下 输入:set nu 显示行号输入:set nonu 不显示行号 B、 cluster-enabled 该属性用于开启 Redis 的集群模式。
C、 cluster-config-file 该属性用于指定集群节点的配置文件。该文件会在第一次节点启动时自动生成其生成的路径是在 dir 属性指定的工作目录中。 在集群节点信息发生变化 后如节点下线、故障转移等节点会自动将集群状态信息保存到该配置文件中。 不过该属性在这里仍保持注释状态。在后面的每个节点单独的配置文件中配置它。
D、 cluster-node-timeout 用于指定 “集群节点” 间通信的 超时时间阈值单位毫秒。
⭐️6 修改 redis6380.conf
# 加上
cluster-config-file nodes-6380.conf仅添加一个 cluster-config-file 属性即可。
⭐️7 复制 5 个 配置文件 使用 redis6380.conf 复制出 5 个配置文件 redis6381.conf 、 redis6382.conf 、 redis6383.conf 、redis6384.conf 、 redis6385.conf 。
cp redis6380.conf redis6381.conf
cp redis6380.conf redis6382.conf
cp redis6380.conf redis6383.conf
cp redis6380.conf redis6384.conf
cp redis6380.conf redis6385.confcluster-dis 中出现了 7 个配置文件。 ⭐️8 修改 5 个配置文件 修改5 个配置文件 redis6381.conf 、 redis6382.conf 、 redis6383.conf 、 redis6384.conf 、redis6385.conf 的内容将其中所有涉及 的 端口号 全部替换为当前文件名称中的端口号。例如下面的是 redis6381.conf 的配置文件内容。
# 进入6381-6385 5个配置文件分别修改
vim redis6381.conf# 在命令模式下输入将6380全部替换为6381
:%s/6380/6381 # 保存
:x6.2.2 系统启动与关闭
⭐️1 启动节点 启动所有 Redis 节点。
redis-server redis6380.conf
redis-server redis6381.conf
redis-server redis6382.conf
redis-server redis6383.conf
redis-server redis6384.conf
redis-server redis6385.conf此时查看 cluster-dis 目录可以看到生成了 6 个 nodes 的配置文件。 ⭐️2 创建系统 6个节点启动后它们仍是 6 个独立的 Redis 通过 redis-cli --cluster create 命令可将 6个节点创建了一个分布式系统。
# ip 换成自己的
redis-cli --cluster create --cluster-replicas 1 192.168.216.128:6380 192.168.216.128:6381 192.168.216.128:6382 192.168.216.128:6383 192.168.216.128:6384 192.168.216.128:6385enspi;该命令用于将指定的 6 个节点连接为一个分布式系统。 --cluster replicas 1 指定每个 master 会带有一个 slave 作为副本。 回车后会立即看到如下日志 输入 yes 后回车系统就会将以上显示的动态配置信息真正的应用到节点上然后就可可看到如下日志 ⭐️3 测试系统
redis-cli -c -p 6380 cluster nodes通过 cluster nodes 命令可以查看到系统中各节点的关系及连接情况。只要能看到每个节点给出 connected 就说明分布式系统已经成功搭建。不过对于客户端连接命令 redis-cli 需要注意两点
redis-cli 带有 -c 参数表示这是要连接一个“集群”而非是一个节点。端口号可以使用 6 个中的任意一个。
⭐️4 关闭系统 对于分布式系统的关闭只需将各个节点 shutdown 即可 。
redis-cli -p 6380 shutdown分布式系统启停脚本
由于集群启动要一下启动好几个所以可以写一个脚本 start-redis-cluster.sh 进行启动
#!/bin/bash
rm -rf dump638*.rdb
rm -rf nodes-638*.confredis-server redis6380.conf
redis-server redis6381.conf
redis-server redis6382.conf
redis-server redis6383.conf
redis-server redis6384.conf
redis-server redis6385.confredis-cli --cluster create --cluster-replicas 1 192.168.216.128:6380 192.168.216.128:6381 192.168.216.128:6382 192.168.216.128:6383 192.168.216.128:6384 192.168.216.128:6385# 再将 start-redis-cluster.sh 设置为可执行文件
chmod 755 start-redis-cluster.sh关闭脚本
#!/bin/bash
redis-cli -p 6380 shutdown
redis-cli -p 6381 shutdown
redis-cli -p 6382 shutdown
redis-cli -p 6383 shutdown
redis-cli -p 6384 shutdown
redis-cli -p 6385 shutdownps aux | grep redis# 再将 start-redis-cluster.sh 设置为可执行文件
chmod 755 shutdown-redis-cluster.sh脚本写好后运行脚本进行分布式系统启停
# 开启
./start-redis-cluster.sh# 查看是否启动成功
redis-cli -c -p 6381 cluster nodes# 关闭
./shutdown-redis-cluster.sh注意生产环境下是在真实的主机上这些脚本是用不上的 6.3 集群操作
6.3.1 连接集群 无论要怎样操作分布式系统都需要首先连接上。
redis-cli -c -p 6380与之前单机连接相比的唯一区别就是增加了参数 -c 。
6.3.2 写入数据
⭐️1 key 单个写入 无论 value 类型为 String 还是 List 、 Set 等集合类型只要写入时操作的是一个 key 那么在分布式系统中就没有问题。例如 ⭐️2 key 批量操作 对一次写入多个 key 的操作由于多个 key 会计算出多个 slot 多个 slot 可能会对应多个节点。而由于一次只能写入一个节点所以该操作会报错。 不过系统也提供了一种对批量 key 的操作方案为这些 key 指定一个统一的 group 让这个 group 作为计算 slot 的唯一值。 6.3.3 集群查询
⭐️1 查询 key 的 slot 通过 cluster keyslot 可以查询指定 key 的 slot 。例如下面是查询 emp 的 slot 。
cluster keyslot emp⭐️2 查询 slot 中 key 的数量 通过 cluster countkeysinslot 命令可以查看到指定 slot 所包含的 key 的个数。
cluster countkeysinslot 13178⭐️3 查询 slot 中的 key 通过 cluster getkeysinslot 命令可以查看当前主机指定 slot 所包含的 key 。
cluster getkeysinslot 13178 36.3.4 故障转移 分布式系统中的某个 master 如果出现宕机那么其相应的 slave 就会自动晋升为 master 。 如果原 master 又重新启动了那么原 master 会自动变为新 master 的 slave 。
⭐️1 模拟故障 通过 cluster nodes 命令可以查看系统的整体架构及连接情况。 当然也可以通过 info replication 查看当前客户端连接的节点的角色。可以看到 6382 节点是 master 其 slave 为 6384 节点 。 为了模拟 6382 宕机直接将其 shutdown 。 通过客户端连接上 6384 节点后可以查看到其已经自动晋升为了 master 。
redis-cli -c -p 6384重启 6382 节点后查看其角色发现其 自动成为 了 6384 节点的 slave 。 之所以 6382 能被发现找到原来那个 master 是因为原来就在这个分布式系统里面所有的配置都有如果再加一个新的节点就不会那么简单了 ⭐️2 全覆盖需求 如果某 slot 范围对应节点的 master 与 slave 全部宕机那么整个分布式系统是否还可以对外提供读服务就取决于属性 cluster-require-full-coverage 的设置。 该属性有两种取值
yes 默认值。要求所有 slot 节点必须全覆盖的情况下系统才能运行。no : slot 节点不全的情况下系统也可以提供查询服务。
6.3.5 集群扩容 下面要在 正在运行的 分布式系统中添加 两个新的节点端口号为 6386 的节点为 master 节点其下会有一个端口号为 6387 的 slave 节点。
⭐️1 复制并修改 2 个配置文件 使用 redis6380.conf 复制出 2 个配置文件 redis6386.conf 与 redis6387.conf 并修改其中的各处端口号为相应端口号为集群扩容做前期准备。
⭐️2 启动系统 与 2 个节点 由于要演示的是在分布式系统运行期间的动态扩容所以这里先启动分布式系统。 要添加的两个节点是两个 Redis 所以需要先将它们启动。只不过在没有添加到分布式系统之前它们两个是孤立节点每个节点与其它任何节点都没有关系。
redis-server redis6386.conf
redis-server redis6387.conf⭐️3 添加 master 节点
redis-cli -c --cluster add-node 192.168.216.128:6386 192.168.216.128:6380通过命令 redis-cli --cluster add-node {newHost}:{newPort} {existHost}:{existPort} 可以将新的节点添加到系统中。 其中 {newHost}:{newPort} 是新添加节点的地址{existHost}:{existPort} 是原系统中的任意节点地址。 添加成功后可看到如下日志。 添加成功后通过 redis-cli -c -p 6386 cluster nodes 命令可以看到其它 master 节点都分配有 slot 只有新添加的 master 还没有相应的 slot 。当然通过该命令也可以看到该新节点的动态 ID 。
redis-cli -c -p 6386 cluster nodes⭐️4 分配 slot 为新的 master 分配的 slot 来自于其它节点总 slot 数量并不会改变。所以 slot 分配过程本质是一个 slot 的移动过程。 通过 redis-cli -c --cluster reshard {existIP}:{existPort} 命令可开启 slot 分配流程。其中地址 {existIP}:{existPort} 为分布式系统中的任意节点地址。
redis-cli -c --cluster reshard 192.168.216.128:6380该流程中会首先查询出当前节点的 slot 分配情况。 然后开始 QA 交互。一共询问了四个问题 这里有三个
准备移动多少 slot准备 由谁 来接收移动的 slot选择要移动 slot 的源节点。有两种方案。 如果选择键入 all 则所有已存在 slot 的节点都将作为 slot 源节点即该方案将进行一次 slot 全局大分配。也可以选择其它部分节点作为 slot 源节点 。此时将源节点的动态 ID 复制到这里每个 ID 键入完毕后回车然后再复制下一个 slot 源节点动态 ID 直至最后一个键入完毕回车后再键入 done 。 这里键入的是 all 进行全局大分配。 其首先会检测指定的 slot 源节点的数据然后制定出 reshard 的方案。 这里会再进行一次 QA 交互询问是否想继续处理 推荐的方案。键入 yes 然后开始真正的全局分配直至完成。 此时再通过 redis-cli -c -p 6386 cluster nodes 命令查看节点信息可以看到 6386 节点中已经分配了 slot 只不过分配的 slot 编号 并不连续。 master 节点新增完成。 ⭐️5 添加 slave 节点 现要将 6387 节点添加为 6386 节点的 slave 。 当然首先要确保 6387 节点的 Redis 是启动状态。 通过 redis-cli --cluster add-node {newHost}:{newPort} {existHost}:{existPort} --cluster-slave --cluster-master-id masterID 命令可将新添加的节点直接添加为指定 master 的 slave 。
redis-cli --cluster add-node 192.168.216.128:6387 192.168.216.128:6380 --cluster-slave --cluster-master-id 5bdccf9f756957e268c7e7d73c3dcec1d3c941be回车后可看到如下的日志 说明添加成功。 此时再通过 redis-cli -c -p 6386 cluster nodes 命令可以看到其已经添加成功且为指定 master 的 slave 。 6.3.6 集群收缩 下面要将 slave 节点 6387 与 master 节点 6386 从分布式系统中删除。
⭐️1 删除 slave 节点 对于 slave 节点可以直接通过 redis-cli --cluster del-node delHost:delPort delNodeID 命令删除。
redis-cli --cluster del-node 192.168.216.128:6387 8242a1ad50eef3e52cb1b72d1192e98a2d56676f此时再查看集群发现已经没有了 6387 节点。 ⭐️2 移出 master 的 slot 在删除一个 master 之前必须要保证该 master 上 没有分配 slot 。否则无法删除。所以在删除一个 master 之前需要先将其上分配的 slot 移出。
redis-cli -c --cluster reshard 192.168.216.128:6380以上交互指定的是将 6386 节点中的 1999 个 slot 移动到 6380 节点。 注意
要删除的节点所包含的 slot 数量在前面检测结果中都是可以看到的例如 6386 中的并不是 2000 个而是 1999 个What is the receiving node ID? 仅能指定一个接收节点回车后继续。再输入源节点的动态IP;输入done 此时再查看发现 6386 节点中已经没有 slot 了变成了 6380 的 slave。 ⭐️3 删除 master 节点 此时就可以删除 6386 节点了。
redis-cli --cluster del-node 192.168.216.128:6386 ab090f5fd43cc5acb4b860bff28cf2461844cd2e此时再查看集群发现已经没有了 6386节点。 6.4 分布式系统的限制 Redis 的分布式系统存在一些使用限制
仅支持 0 号 数据库批量 key 操作支持有限分区 仅限于 key事务支持有限不支持 分级管理 注仅供学习参考如有不足欢迎指正