谷粒商城のRedis&ES&Rabbit MQ集群

文章目录


前言

本篇是谷粒商城集群部署篇,搭建Redis、ES、Rabbit MQ集群实践的个人笔记,也是谷粒商城笔记的最后一篇。集群相关的理论性内容,会放在面试篇的笔记中。


一、搭建Redis集群

采用3主节点+3从节点的架构,在docker上创建实例:

shell 复制代码
for port in $(seq 7001 7006); do
  mkdir -p /mydata/redis/node-${port}/conf
  touch /mydata/redis/node-${port}/conf/redis.conf
  cat << 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
EOF
  docker 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实例创建完成:
  进入其中一个主节点,设置集群信息:

shell 复制代码
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指定集群模式,操作其中一个主节点:

shell 复制代码
redis-cli -c -h 192.168.101.128 -p 7001

set一个键值,因为k1经过hash运算,被路由到了7003的hash槽,所以自动进入了7003节点:
  再模拟一下宕机的情况,将7001主节点下线:

shell 复制代码
docker stop redis-7001

然后进入7002的内部:

shell 复制代码
docker exec -it redis-7002 bash
redis-cli -c -h 192.168.101.128 -p 7002

查看集群状态,7004从从节点被提升到了主节点,如果将7001重新上线,会成为7004的从节点

三、搭建ES集群

首先临时修改配置:

shell 复制代码
sysctl -w vm.max_map_count=262144

Docker 创建容器时默认采用 bridge 网络,自行分配 ip,不允许自己指定。在实际部署中,我们需要指定容器 ip,不允许其自行分配 ip,尤其是搭建集群时,固定 ip 是必须的,可以创建一个新的 bridge 网络:

shell 复制代码
docker network create --driver bridge --subnet=172.18.0.0/16 --gateway=172.18.1.1 mynet

创建master节点:

bash 复制代码
for port in $(seq 1 3); do
    # 创建目录结构并设置权限
    mkdir -p /mydata/elasticsearch/master-${port}/config
    mkdir -p /mydata/elasticsearch/master-${port}/data
    chmod -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节点选举:

shell 复制代码
for port in $(seq 4 6); do
    # 创建目录结构并设置权限
    mkdir -p /mydata/elasticsearch/node-${port}/config
    mkdir -p /mydata/elasticsearch/node-${port}/data
    chmod -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节点宕机了,那么消费者也就无法进行消费。镜像集群模式,数据会主动在节点之间进行同步,而不是在读取数据的时候才临时拉取。

首先创建出对应的文件夹和目录:

shell 复制代码
mkdir /mydata/rabbitmq
cd rabbitmq/
mkdir rabbitmq01 rabbitmq02 rabbitmq03

启动三个实例:

shell 复制代码
# 启动 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

  可以在页面上访问:
  然后让每个节点加入集群:

shell 复制代码
docker exec -it rabbitmq01 /bin/bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
exit
shell 复制代码
docker exec -it rabbitmq02 /bin/bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
rabbitmqctl start_app
exit
shell 复制代码
docker exec -it rabbitmq03 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq01
rabbitmqctl start_app
exit

登录网页,节点已经加入了集群。

  设置镜像集群模式(RabbitMQ 3.8 版本开始,队列镜像功能已经被废弃,推荐使用仲裁队列来实现高可用。)

shell 复制代码
docker exec -it rabbitmq01 bash
rabbitmqctl set_policy -p / ha "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'

相关推荐
弗锐土豆13 分钟前
maven工程修改jdk编译版本的几种方法
java·eclipse·maven·编译·版本
finbarr4522 分钟前
搭建es环境
大数据·elasticsearch·搜索引擎
尘浮生25 分钟前
Java项目实战II基于Spring Boot的工作流程管理系统设计与实现(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·微信·微信小程序·小程序
2401_8543910830 分钟前
全面掌握Spring Boot异常处理:策略与实践
java·spring boot·后端
喜欢猪猪32 分钟前
手写模拟Spring Boot自动配置功能
java·spring boot·后端
打破砂锅问到底00732 分钟前
技术周总结 11.11~11.17 周日(Js JVM XML)
java
弗锐土豆43 分钟前
工业生产安全-安全帽第一篇-opencv及java开发环境搭建
java·opencv·安全·工业·生产
java小吕布1 小时前
Java NIO 深度解析:构建高效的 I/O 操作
java·开发语言·nio
不会就选C.1 小时前
设计模式之单例模式和工厂模式(代码+举例)
java·spring boot·设计模式