redis分片集群的部署和使用教程
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">使用docker在虚拟机部署</a></li><li><a href="#_label1">SpringBoot 整合redis集群</a></li><li><a href="#_label2">redis分片集群一些须知</a></li><ul class="second_class_ul"><li><a href="#_lab2_2_0">哈希槽</a></li><li><a href="#_lab2_2_1">redis的拓展和压缩</a></li></ul></ul></div><p class="maodian"><a name="_label0"></a></p><h2>使用docker在虚拟机部署</h2><p>脚本是个好东西。使用脚本部署那是相当的快速。下面介绍一下我使用脚本+docker部署的步骤吧。</p>
<ol><li>首先拉取镜像,至少是可以分片的版本。</li></ol>
<div class="jb51code"><pre class="brush:bash;">pull images redis:5.0.9-alpine3.11</pre></div>
<ol start="2"><li>选取一个工作目录创建一个redis配置文件的模板文件(redis-cluster.tmpl )</li></ol>
<div class="jb51code"><pre class="brush:plain;">port ${PORT}
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 你的虚拟机IP
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}
appendonly yes</pre></div>
<ol start="3"><li>使用脚本批量创建目录和配置文件 init.sh</li></ol>
<div class="jb51code"><pre class="brush:bash;">#!/bin/bash
for port in $(seq 8001 8006);
do
mkdir -p ./${port}/conf
PORT=${port} envsubst < ./redis/redis-cluster.tmpl > ./${port}/conf/redis.conf
mkdir -p ./${port}/data;
done</pre></div>
<ol start="4"><li>给脚本权限并运行脚本</li></ol>
<div class="jb51code"><pre class="brush:bash;">chmod +x init.sh
./init.sh</pre></div>
<ol start="5"><li>创建docker-compose.yml文件<br />这里redis对应的版本按照自己拉取的改一下。</li></ol>
<div class="jb51code"><pre class="brush:plain;">version: '3.8'
services:
redis-8001:
image: redis:latest
container_name: redis-8001
ports:
- "8001:8001"
- "18001:18001"
volumes:
- ./8001/conf/redis.conf:/usr/local/etc/redis/redis.conf
- ./8001/data:/data
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-cluster-net
redis-8002:
image: redis:latest
container_name: redis-8002
ports:
- "8002:8002"
- "18002:18002"
volumes:
- ./8002/conf/redis.conf:/usr/local/etc/redis/redis.conf
- ./8002/data:/data
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-cluster-net
redis-8003:
image: redis:latest
container_name: redis-8003
ports:
- "8003:8003"
- "18003:18003"
volumes:
- ./8003/conf/redis.conf:/usr/local/etc/redis/redis.conf
- ./8003/data:/data
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-cluster-net
redis-8004:
image: redis:latest
container_name: redis-8004
ports:
- "8004:8004"
- "18004:18004"
volumes:
- ./8004/conf/redis.conf:/usr/local/etc/redis/redis.conf
- ./8004/data:/data
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-cluster-net
redis-8005:
image: redis:latest
container_name: redis-8005
ports:
- "8005:8005"
- "18005:18005"
volumes:
- ./8005/conf/redis.conf:/usr/local/etc/redis/redis.conf
- ./8005/data:/data
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-cluster-net
redis-8006:
image: redis:latest
container_name: redis-8006
ports:
- "8006:8006"
- "18006:18006"
volumes:
- ./8006/conf/redis.conf:/usr/local/etc/redis/redis.conf
- ./8006/data:/data
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-cluster-net
networks:
redis-cluster-net:
driver: bridge</pre></div>
<ol start="6"><li>在创建dcoker-compose.yml对应的目录下执行该文件</li></ol>
<div class="jb51code"><pre class="brush:plain;">docker compose up -d</pre></div>
<ol start="7"><li>随便进入一个容器内部搭建分片集群</li></ol>
<div class="jb51code"><pre class="brush:bash;">docker exec -it reids-8001 redis-cli --cluster create \
192.168.59.128:8001 \
192.168.59.128:8002 \
192.168.59.128:8003\
192.168.59.128:8004 \
192.168.59.128:8005 \
192.168.59.128:8006 \
--cluster-replicas 1// 副本数量·1前三个节点成为主节点,后面三个节点成为从节点</pre></div>
<p>至此大功告成。</p>
<p class="maodian"><a name="_label1"></a></p><h2>SpringBoot 整合redis集群</h2>
<ol><li>导入依赖</li></ol>
<div class="jb51code"><pre class="brush:plain;"><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency></pre></div>
<ol start="2"><li>配置yml</li></ol>
<div class="jb51code"><pre class="brush:plain;">spring:
data:
redis:
# 集群节点配置:填写你的虚拟机IP和端口
cluster:
nodes:
- 192.168.59.128:8001
- 192.168.59.128:8002
- 192.168.59.128:8003
- 192.168.59.128:8004
- 192.168.59.128:8005
# 最大重定向次数
max-redirects: 3
# 连接超时时间
timeout: 3000ms
# Lettuce连接池配置 (可选但推荐)
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: -1ms</pre></div>
<ol start="3"><li>配置读写分离</li></ol>
<div class="jb51code"><pre class="brush:java;">@Configuration
public class RedisConfig {
@Bean
public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer() {
return clientConfigurationBuilder -> clientConfigurationBuilder
.readFrom(ReadFrom.REPLICA_PREFERRED);// 优先从从节点读取
}
}</pre></div>
<p>可选取的读写分离政策:</p>
<ol><li>ReadFrom.MASTER // 只从主节点读取(强一致性)</li><li>ReadFrom.MASTER_PREFERRED // 优先从主节点读取</li><li>ReadFrom.REPLICA // 只从从节点读取</li><li>ReadFrom.REPLICA_PREFERRED // 优先从从节点读取(推荐)</li><li>ReadFrom.NEAREST // 从最近的节点读取</li><li>ReadFrom.ANY // 从任意节点读取</li></ol>
<p class="maodian"><a name="_label2"></a></p><h2>redis分片集群一些须知</h2>
<p class="maodian"><a name="_lab2_2_0"></a></p><h3>哈希槽</h3>
<ol><li>分片集群一共有为0-16383 slot,存储数据和读取数据时,在哪一个节点进行操作,是根据key的有效值,根据CRC16 算法算取哈希值,然后对 16384 进行取模,得到的值就是slot值。</li><li>key的有效值分为两种情况<br />a.key中没有{},整个key都是有效值<br />b. key中有{},只有{}中的字符才是有效值。<br />3.根据key的有效值的特性,我们可以把同一类型的数据存储在相同的slot下,减少切换节点带来的不必要的性能消耗。比如存储用户的数据 ,在设计key时,我们可以统一在和用户相关的key前加上:{user}。</li></ol>
<p class="maodian"><a name="_lab2_2_1"></a></p><h3>redis的拓展和压缩</h3>
<ol><li>添加一个新的节点</li></ol>
<div class="jb51code"><pre class="brush:plain;">redis-cli --cluster add-node <新节点IP:端口> <集群中任意已知节点IP:端口></pre></div>
<p>默认时主节点,此时新节点还没有分配任何的slot,需要重新分配slot。</p>
<div class="jb51code"><pre class="brush:plain;">redis-cli --cluster reshard <集群中任意已知节点IP:端口></pre></div>
<p>如果要设置成从节点</p>
<div class="jb51code"><pre class="brush:plain;"># 连接新节点
redis-cli -h <新从节点IP> -p <新从节点端口>
# 设置主节点
CLUSTER REPLICATE <目标主节点ID></pre></div>
<ol start="2"><li>删除节点<br />如果删除的从节点,因为从节点没有任何的slot,所以可以直接删除</li></ol>
<div class="jb51code"><pre class="brush:plain;">redis-cli --cluster del-node <集群中任意已知节点IP:端口> <要删除的从节点ID></pre></div>
<p>删除主节点,把主节点的slot迁移到其他主节点在进行删除</p>
<div class="jb51code"><pre class="brush:plain;">redis-cli --cluster reshard <集群中任意已知节点IP:端口></pre></div>
頁:
[1]