文章目录
- 前言
- 一、搭建Redis集群
- 三、搭建ES集群
- 三、搭建Rabbit MQ集群
前言
本篇是谷粒商城集群部署篇,搭建Redis、ES、Rabbit MQ集群实践的个人笔记,也是谷粒商城笔记的最后一篇。集群相关的理论性内容,会放在面试篇的笔记中。
一、搭建Redis集群
采用3主节点+3从节点的架构,在docker上创建实例:
for port in $(seq 7001 7006); domkdir -p /mydata/redis/node-${port}/conftouch /mydata/redis/node-${port}/conf/redis.confcat << EOF > /mydata/redis/node-${port}/conf/redis.conf
port ${port}
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 192.168.101.128
cluster-announce-port ${port}
cluster-announce-bus-port 1${port}
appendonly yes
EOFdocker run -p ${port}:${port} -p 1${port}:1${port} \--name redis-${port} \-v /mydata/redis/node-${port}/data:/data \-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \-d redis:5.0.7 redis-server /etc/redis/redis.conf
done
六个Redis实例创建完成:
进入其中一个主节点,设置集群信息:
docker exec -it redis-7001 bash
redis-cli --cluster create 192.168.101.128:7001 192.168.101.128:7002 192.168.101.128:7003 192.168.101.128:7004 192.168.101.128:7005 192.168.101.128:7006 --cluster-replicas 1
7001,7002,7003是主节点,7005是7001的从节点,7006是7002的从节点,7004是7003的从节点:
使用cli命令-c指定集群模式,操作其中一个主节点:
redis-cli -c -h 192.168.101.128 -p 7001
set一个键值,因为k1经过hash运算,被路由到了7003的hash槽,所以自动进入了7003节点:
再模拟一下宕机的情况,将7001主节点下线:
docker stop redis-7001
然后进入7002的内部:
docker exec -it redis-7002 bash
redis-cli -c -h 192.168.101.128 -p 7002
查看集群状态,7004从从节点被提升到了主节点,如果将7001重新上线,会成为7004的从节点
三、搭建ES集群
首先临时修改配置:
sysctl -w vm.max_map_count=262144
Docker 创建容器时默认采用 bridge 网络,自行分配 ip,不允许自己指定。在实际部署中,我们需要指定容器 ip,不允许其自行分配 ip,尤其是搭建集群时,固定 ip 是必须的,可以创建一个新的 bridge 网络:
docker network create --driver bridge --subnet=172.18.0.0/16 --gateway=172.18.1.1 mynet
创建master节点:
for port in $(seq 1 3); do# 创建目录结构并设置权限mkdir -p /mydata/elasticsearch/master-${port}/configmkdir -p /mydata/elasticsearch/master-${port}/datachmod -R 777 /mydata/elasticsearch/master-${port}# 生成 Elasticsearch 配置文件cat << EOF > /mydata/elasticsearch/master-${port}/config/elasticsearch.yml
cluster.name: my-es # 集群的名称,同一个集群该值必须设置成相同的
node.name: es-master-${port} # 该节点的名字
node.master: true # 该节点有机会成为 master 节点
node.data: false # 该节点可以存储数据
network.host: 0.0.0.0
http.host: 0.0.0.0 # 所有 http 均可访问
http.port: 920${port}
transport.tcp.port: 930${port}
# discovery.zen.minimum_master_nodes: 2 # 保证集群中的节点可以知道其余 N 个有 master 资格的节点
discovery.zen.ping_timeout: 10s # 设置集群中自动发现其他节点时 ping 连接的超时时间
discovery.seed_hosts: ["172.18.0.21:9301", "172.18.0.22:9302", "172.18.0.23:9303"] # 设置集群 Master 节点的初始列表
cluster.initial_master_nodes: ["172.18.0.21"] # 新集群初始时的候选主节点
EOF# 运行 Docker 容器docker run --name elasticsearch-node-${port} \-p 920${port}:920${port} \-p 930${port}:930${port} \--network=mynet \--ip 172.18.0.2${port} \-e ES_JAVA_OPTS="-Xms300m -Xmx300m" \-v /mydata/elasticsearch/master-${port}/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \-v /mydata/elasticsearch/master-${port}/data:/usr/share/elasticsearch/data \-v /mydata/elasticsearch/master-${port}/plugins:/usr/share/elasticsearch/plugins \-d elasticsearch:7.4.2
done
创建node节点,和master节点的区别在于不参与master节点选举:
for port in $(seq 4 6); do# 创建目录结构并设置权限mkdir -p /mydata/elasticsearch/node-${port}/configmkdir -p /mydata/elasticsearch/node-${port}/datachmod -R 777 /mydata/elasticsearch/node-${port}# 生成 Elasticsearch 配置文件cat << EOF > /mydata/elasticsearch/node-${port}/config/elasticsearch.yml
cluster.name: my-es # 集群的名称,同一个集群该值必须设置成相同的
node.name: es-node-${port} # 该节点的名字
node.master: false # 该节点不会成为 master 节点
node.data: true # 该节点可以存储数据
network.host: 0.0.0.0
# network.publish_host: 192.168.101.128 # 如果需要通信,可以设置为本机外网 IP
http.host: 0.0.0.0 # 所有 http 均可访问
http.port: 920${port}
transport.tcp.port: 930${port}
# discovery.zen.minimum_master_nodes: 2 # 官方推荐(N/2)+1 来保证集群的安全性
discovery.zen.ping_timeout: 10s # 设置集群中自动发现其他节点时 ping 连接的超时时间
discovery.seed_hosts: ["172.18.0.21:9301", "172.18.0.22:9302", "172.18.0.23:9303"] # 设置 Master 节点初始列表
cluster.initial_master_nodes: ["172.18.0.21"] # 新集群初始时的候选主节点
EOF# 运行 Docker 容器docker run --name elasticsearch-node-${port} \-p 920${port}:920${port} \-p 930${port}:930${port} \--network=mynet \--ip 172.18.0.2${port} \-e ES_JAVA_OPTS="-Xms300m -Xmx300m" \-v /mydata/elasticsearch/node-${port}/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \-v /mydata/elasticsearch/node-${port}/data:/usr/share/elasticsearch/data \-v /mydata/elasticsearch/node-${port}/plugins:/usr/share/elasticsearch/plugins \-d elasticsearch:7.4.2
done
全部启动完毕后,通过docker logs命令可以查看某个节点的同步过程,大致说明了:
- Elasticsearch 集群 my-es 的 es-node-4 节点成功应用了来自 es-master-1 主节点的集群状态变更。
- 变更内容是新节点 es-node-6 加入到集群中。 在网页上也可以访问到集群:
ES会在标记了node.master: true
的节点之中,选举一个主节点,加上*号
如果将主节点强制下线,会重新选举一个主节点:
三、搭建Rabbit MQ集群
Rabbit MQ集群本次选用镜像集群
。简单的说,普通集群
模式下,假设我有A,B,C三个节点,消费者需要从C节点中获取信息,但是该消息现在只存在于A节点的队列中,这时MQ会将消息从A节点的队列复制
到C节点的队列,消费者再进行消费。如果A节点宕机了,那么消费者也就无法进行消费。镜像集群
模式,数据会主动在节点之间进行同步,而不是在读取数据的时候才临时拉取。
首先创建出对应的文件夹和目录:
mkdir /mydata/rabbitmq
cd rabbitmq/
mkdir rabbitmq01 rabbitmq02 rabbitmq03
启动三个实例:
# 启动 RabbitMQ 容器 rabbitmq01
docker run -d \--hostname rabbitmq01 \--name rabbitmq01 \-v /mydata/rabbitmq/rabbitmq01:/var/lib/rabbitmq \-p 15673:15672 \-p 5673:5672 \-e RABBITMQ_ERLANG_COOKIE='moon' \rabbitmq:management# 启动 RabbitMQ 容器 rabbitmq02
docker run -d \--hostname rabbitmq02 \--name rabbitmq02 \-v /mydata/rabbitmq/rabbitmq02:/var/lib/rabbitmq \-p 15674:15672 \-p 5674:5672 \-e RABBITMQ_ERLANG_COOKIE='moon' \--link rabbitmq01:rabbitmq01 \rabbitmq:management# 启动 RabbitMQ 容器 rabbitmq03
docker run -d \--hostname rabbitmq03 \--name rabbitmq03 \-v /mydata/rabbitmq/rabbitmq03:/var/lib/rabbitmq \-p 15675:15672 \-p 5675:5672 \-e RABBITMQ_ERLANG_COOKIE='moon' \--link rabbitmq01:rabbitmq01 \--link rabbitmq02:rabbitmq02 \rabbitmq:management
可以在页面上访问:
然后让每个节点加入集群:
docker exec -it rabbitmq01 /bin/bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
exit
docker exec -it rabbitmq02 /bin/bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
rabbitmqctl start_app
exit
docker exec -it rabbitmq03 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
rabbitmqctl start_app
exit
登录网页,节点已经加入了集群。
设置镜像集群模式(RabbitMQ 3.8 版本开始,队列镜像功能已经被废弃,推荐使用仲裁队列来实现高可用。)
docker exec -it rabbitmq01 bash
rabbitmqctl set_policy -p / ha "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'