docker 快速构建 redis 主从集群(5分钟的事情)
文章目录
前言:
昨天有个小伙伴问我,想搭建redis 主从,并且集群。可是他查询了很多网站,就是搞不定,一大堆的配置文件,看了,都心疼。
在这里我将我搭建的redis集群的代码共享出来给大家看看,整个搭建也就5分钟的事情,写成脚本也就是30秒的事情。
1 规划
1.1 redis 镜像下载
在下载镜像的时候,使用redis:5.0,能够快速的创建容器,并且
[root@localhost ~]# docker pull redis:5.0
Trying to pull repository docker.io/library/redis ...
5.0: Pulling from docker.io/library/redis
123275d6e508: Pull complete
f2edbd6a658e: Pull complete
66960bede47c: Pull complete
79dc0b596c90: Pull complete
de36df38e0b6: Pull complete
602cd484ff92: Pull complete
Digest: sha256:1d0b903e3770c2c3c79961b73a53e963f4fd4b2674c2c4911472e8a054cb5728
Status: Downloaded newer image for docker.io/redis:5.0
1.2 构建redis容器
1.2.1 配置说明:
–name redis7001 创建的名称
-p 7000:6379 端口映射
–requirepass “123456” 创建密码
–cluster-enabled yes 集群模式
–protected-mode no 关闭保护模式
-appendonly yes 开启AOF 持久化的模式(默认为RDB)
Redis默认采用异步的方式将数据存放到磁盘上,这个模式对大部份应用来说是足够好的,但是在Redis进程或电源发生故障的情况下,可能会造成小部份的数据丢失,这取决于配置的保存时间点。 Appendonly是一种能够提供非常好的持久化的模式,例如使用默认的Fsync方案,Redis能在发生服务器电源故障或操作系统仍然正常运行但Redis进程莫名挂掉的情况下,只丢失1秒的数据。 AOF与RDB模式可以同时启用,这并不冲突。如果AOF是可用的,那Redis启动时将自动加载AOF,这个文件能够提供更好的持久性保障。
docker run --name redis7001 -p 7001:6379 -d redis:5.0 redis-server --requirepass "123456" --appendonly yes --protected-mode no --cluster-enabled yes
docker run --name redis7002 -p 7002:6379 -d redis:5.0 redis-server --requirepass "123456" --appendonly yes --protected-mode no --cluster-enabled yes
docker run --name redis7003 -p 7003:6379 -d redis:5.0 redis-server --requirepass "123456" --appendonly yes --protected-mode no --cluster-enabled yes
docker run --name redis7004 -p 7004:6379 -d redis:5.0 redis-server --requirepass "123456" --appendonly yes --protected-mode no --cluster-enabled yes
docker run --name redis7005 -p 7005:6379 -d redis:5.0 redis-server --requirepass "123456" --appendonly yes --protected-mode no --cluster-enabled yes
docker run --name redis7006 -p 7006:6379 -d redis:5.0 redis-server --requirepass "123456" --appendonly yes --protected-mode no --cluster-enabled yes
docker run --name redis7007 -p 7007:6379 -d redis:5.0 redis-server --requirepass "123456" --appendonly yes --protected-mode no --cluster-enabled yes
1.2.2 编写shell
for port in `seq 7001 7007`;do
docker run -p ${port}:6379 --name redis${port} \
-d redis:5.0 redis-server --requirepass "123456" \
--appendonly yes --protected-mode no \
--cluster-enabled yes
done
1.2.3 shell创建容器
[root@localhost ~]# for port in `seq 7001 7007`;do
> docker run -p ${port}:6379 --name redis${port} \
> -d redis:5.0 redis-server --requirepass "123456" \
> --appendonly yes --protected-mode no \
> --cluster-enabled yes
> done;
b88066b05bb0c32438330c9c9b7d9413b9de02543bc14b349e43d23076b3be34
3016e9c29e8f00308b793f11c5428e77659e65221612721e3d50e24ac9aa8702
6acd7ab0edd322177577cb76eff75a6dc20f3bd7e8d5ea6cbcc8c2cef985710f
62850ab5dfafee2cc438aa1e21f4cf13cbcee49f8e7f35407d0f15071640dc56
3909afb51191315ae1c32452d5c4cb31a1aec8c7d2179f6d5701e8654f5b5214
7e079949c89baa77a2913c9cb945d1338c6604f1dddf770dfb3cafe8f9c91708
aac7b6df3d0fa309e65548928a733a16db7155b073ad40027573838e302e3f21
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aac7b6df3d0f redis:5.0 "docker-entrypoint..." 9 seconds ago Up 9 seconds 0.0.0.0:7007->6379/tcp redis7007
7e079949c89b redis:5.0 "docker-entrypoint..." 9 seconds ago Up 9 seconds 0.0.0.0:7006->6379/tcp redis7006
3909afb51191 redis:5.0 "docker-entrypoint..." 10 seconds ago Up 9 seconds 0.0.0.0:7005->6379/tcp redis7005
62850ab5dfaf redis:5.0 "docker-entrypoint..." 10 seconds ago Up 10 seconds 0.0.0.0:7004->6379/tcp redis7004
6acd7ab0edd3 redis:5.0 "docker-entrypoint..." 10 seconds ago Up 10 seconds 0.0.0.0:7003->6379/tcp redis7003
3016e9c29e8f redis:5.0 "docker-entrypoint..." 11 seconds ago Up 10 seconds 0.0.0.0:7002->6379/tcp redis7002
b88066b05bb0 redis:5.0 "docker-entrypoint..." 11 seconds ago Up 11 seconds 0.0.0.0:7001->6379/tcp redis7001
0a816c1be4f2 mysql "docker-entrypoint..." 12 months ago Up 59 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp liubijun_mysql
[root@localhost ~]#
1.2.4 查看容器ip
for port in `seq 7001 7007`;do
docker inspect redis${port} | grep IPAddress
done
1.2.5 redis容器的ip
[root@localhost ~]# for port in `seq 7001 7007`;do
>
> docker inspect redis${port} | grep IPAddress
> done
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.3",
"IPAddress": "172.17.0.3",
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.4",
"IPAddress": "172.17.0.4",
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.5",
"IPAddress": "172.17.0.5",
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.6",
"IPAddress": "172.17.0.6",
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.7",
"IPAddress": "172.17.0.7",
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.8",
"IPAddress": "172.17.0.8",
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.9",
"IPAddress": "172.17.0.9",
[root@localhost ~]#
1.3 创建集群
1.3.1 根据查询出来的ip 来构建集群
docker exec -it redis7001 /bin/bash
redis-cli -a 123456 --cluster create \
172.17.0.3:6379 172.17.0.4:6379 172.17.0.5:6379 \
172.17.0.6:6379 172.17.0.7:6379 172.17.0.8:6379 \
172.17.0.9:6379 --cluster-replicas 1
1.3.2 集群创建效果
当看到16384 solt 创建成功,则该集群工作已经完成;
[root@localhost ~]# docker exec -it redis7001 /bin/bash
root@b88066b05bb0:/data# redis-cli -a 123456 --cluster create \
> 172.17.0.3:6379 172.17.0.4:6379 172.17.0.5:6379 \
> 172.17.0.6:6379 172.17.0.7:6379 172.17.0.8:6379 \
> 172.17.0.9:6379 --cluster-replicas 1
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Performing hash slots allocation on 7 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.17.0.7:6379 to 172.17.0.3:6379
Adding replica 172.17.0.8:6379 to 172.17.0.4:6379
Adding replica 172.17.0.9:6379 to 172.17.0.5:6379
Adding extra replicas...
Adding replica 172.17.0.6:6379 to 172.17.0.3:6379
M: 75faad2fc556685e8df0e95032f3be2b484ff8cc 172.17.0.3:6379
slots:[0-5460] (5461 slots) master
M: 959be42eb9463c9aead8d3a93a9a3689b24e979b 172.17.0.4:6379
slots:[5461-10922] (5462 slots) master
M: 20d693fea18b392153aa35ac55b7285b36067ab6 172.17.0.5:6379
slots:[10923-16383] (5461 slots) master
S: 2571a7673369d249667702f41daec2bedc9baff4 172.17.0.6:6379
replicates 75faad2fc556685e8df0e95032f3be2b484ff8cc
S: 40cc2a08d5114fff89b0db8990c70b5aa176c6ad 172.17.0.7:6379
replicates 75faad2fc556685e8df0e95032f3be2b484ff8cc
S: 5dfc9647a5173ce0ce31162378293362cebbc81c 172.17.0.8:6379
replicates 959be42eb9463c9aead8d3a93a9a3689b24e979b
S: 26a1f6d3622eb5682ddf579e51fa71dcb814ff45 172.17.0.9:6379
replicates 20d693fea18b392153aa35ac55b7285b36067ab6
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.........
>>> Performing Cluster Check (using node 172.17.0.3:6379)
M: 75faad2fc556685e8df0e95032f3be2b484ff8cc 172.17.0.3:6379
slots:[0-5460] (5461 slots) master
2 additional replica(s)
M: 20d693fea18b392153aa35ac55b7285b36067ab6 172.17.0.5:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 40cc2a08d5114fff89b0db8990c70b5aa176c6ad 172.17.0.7:6379
slots: (0 slots) slave
replicates 75faad2fc556685e8df0e95032f3be2b484ff8cc
S: 26a1f6d3622eb5682ddf579e51fa71dcb814ff45 172.17.0.9:6379
slots: (0 slots) slave
replicates 20d693fea18b392153aa35ac55b7285b36067ab6
S: 5dfc9647a5173ce0ce31162378293362cebbc81c 172.17.0.8:6379
slots: (0 slots) slave
replicates 959be42eb9463c9aead8d3a93a9a3689b24e979b
M: 959be42eb9463c9aead8d3a93a9a3689b24e979b 172.17.0.4:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 2571a7673369d249667702f41daec2bedc9baff4 172.17.0.6:6379
slots: (0 slots) slave
replicates 75faad2fc556685e8df0e95032f3be2b484ff8cc
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
root@b88066b05bb0:/data#
1.3.3 查询集群信息
127.0.0.1:6379> cluster nodes
20d693fea18b392153aa35ac55b7285b36067ab6 172.17.0.5:6379@16379 master - 0 1587519666243 3 connected 10923-16383
40cc2a08d5114fff89b0db8990c70b5aa176c6ad 172.17.0.7:6379@16379 slave 75faad2fc556685e8df0e95032f3be2b484ff8cc 0 1587519669273 5 connected
26a1f6d3622eb5682ddf579e51fa71dcb814ff45 172.17.0.9:6379@16379 slave 20d693fea18b392153aa35ac55b7285b36067ab6 0 1587519666000 7 connected
5dfc9647a5173ce0ce31162378293362cebbc81c 172.17.0.8:6379@16379 slave 959be42eb9463c9aead8d3a93a9a3689b24e979b 0 1587519668263 6 connected
75faad2fc556685e8df0e95032f3be2b484ff8cc 172.17.0.3:6379@16379 myself,master - 0 1587519667000 1 connected 0-5460
959be42eb9463c9aead8d3a93a9a3689b24e979b 172.17.0.4:6379@16379 master - 0 1587519668000 2 connected 5461-10922
2571a7673369d249667702f41daec2bedc9baff4 172.17.0.6:6379@16379 slave 75faad2fc556685e8df0e95032f3be2b484ff8cc 0 1587519667255 4 connected
127.0.0.1:6379>
1.4 常见命令和问题
1.4.1 redis info
# 查询信息,用户未登陆
root@b88066b05bb0:/data# redis-cli info
NOAUTH Authentication required.
#正确打开方式
root@b88066b05bb0:/data# redis-cli -c -a 123456 info
redis info 详解
# Server
redis_version:5.0.9
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:c781f6fafb441952
redis_mode:cluster
os:Linux 3.10.0-693.el7.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:8.3.0
process_id:1
run_id:f931fec8397ee841b70632759c8bdbc517b02edd
tcp_port:6379
uptime_in_seconds:972
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:10461112
executable:/data/redis-server
config_file:
# Clients
connected_clients:1
client_recent_max_input_buffer:4
client_recent_max_output_buffer:0
blocked_clients:0
# Memory
used_memory:1590752
used_memory_human:1.52M
used_memory_rss:10334208
used_memory_rss_human:9.86M
used_memory_peak:1590752
used_memory_peak_human:1.52M
used_memory_peak_perc:100.00%
used_memory_overhead:1499390
used_memory_startup:1449696
used_memory_dataset:91362
used_memory_dataset_perc:64.77%
allocator_allocated:1598192
allocator_active:1798144
allocator_resident:4079616
total_system_memory:8354729984
total_system_memory_human:7.78G
used_memory_lua:37888
used_memory_lua_human:37.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:1.13
allocator_frag_bytes:199952
allocator_rss_ratio:2.27
allocator_rss_bytes:2281472
rss_overhead_ratio:2.53
rss_overhead_bytes:6254592
mem_fragmentation_ratio:6.76
mem_fragmentation_bytes:8806336
mem_not_counted_for_evict:0
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:49694
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0
# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1587518444
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:-1
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:0
aof_enabled:1
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_last_cow_size:0
aof_current_size:0
aof_base_size:0
aof_pending_rewrite:0
aof_buffer_length:0
aof_rewrite_buffer_length:0
aof_pending_bio_fsync:0
aof_delayed_fsync:0
# Stats
total_connections_received:869
total_commands_processed:21
instantaneous_ops_per_sec:0
total_net_input_bytes:190884
total_net_output_bytes:166599
instantaneous_input_kbps:0.38
instantaneous_output_kbps:0.41
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
expired_stale_perc:0.00
expired_time_cap_reached_count:0
evicted_keys:0
keyspace_hits:0
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:0
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0
# Replication
role:master
connected_slaves:0
master_replid:98c62780f60db04d777ca31eb2ab753748744a59
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
# CPU
used_cpu_sys:1.523845
used_cpu_user:0.929174
used_cpu_sys_children:0.011220
used_cpu_user_children:0.001729
# Cluster
cluster_enabled:1
# Keyspace
1.4.2 登陆集群
root@b88066b05bb0:/data# redis-cli -a 123456 -c
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379>
1.4.3 存取
127.0.0.1:6379> set "zhangsan" "lisi"
-> Redirected to slot [12767] located at 172.17.0.5:6379
OK
172.17.0.5:6379> keys *
1) "zhangsan"
172.17.0.5:6379> get zhangsan
"lisi"
172.17.0.5:6379> set wangwu zhaoliu
-> Redirected to slot [9439] located at 172.17.0.4:6379
OK
172.17.0.4:6379> keys *
1) "wangwu"
172.17.0.4:6379>
1.5 完整构建集群的shell
```shell
docker pull redis:5.0
echo “下载完成”
for port in seq 7001 7007
;do
docker run -p
p
o
r
t
:
6379
−
−
n
a
m
e
r
e
d
i
s
{port}:6379 --name redis
port:6379−−nameredis{port}
-d redis:5.0 redis-server --requirepass “123456”
–appendonly yes --protected-mode no
–cluster-enabled yes
done
echo “容器创建完成”
for port in seq 7001 7007
;do
docker inspect redis${port} | grep IPAddress
done
echo “查询容器ip完成”
这里ip为没有做处理,建议小伙伴自己写个批处理,就可以完成了
docker exec -it redis7001 /bin/bash
redis-cli -a 123456 --cluster create
172.17.0.3:6379 172.17.0.4:6379 172.17.0.5:6379
172.17.0.6:6379 172.17.0.7:6379 172.17.0.8:6379
172.17.0.9:6379 --cluster-replicas 1
```