谷粒商城の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"}'

相关推荐
编程修仙3 分钟前
第一篇 认识SpringBoot
java·spring boot
骇客野人7 分钟前
.gitignore文件常用设置
java
bill44715 分钟前
BPMN2.0,flowable工作流,【用户任务】使用【任务监听器】动态设置下一步处理人
java·工作流引擎·flowable·bpmn
Cricyta Sevina15 分钟前
Java 语言多线程核心概念全解析
java·开发语言
shenzhenNBA24 分钟前
如何在python文件中使用日志功能?简单版本
java·前端·python·日志·log
遇印记41 分钟前
javaOCA考点(基础)
java·开发语言·青少年编程
阿里云云原生1 小时前
告别“看不见的内存”!SysOM 如何实现 Java 进程内存全景分析?
java·云原生
Andy工程师1 小时前
Spring Boot 按照以下顺序加载配置(后面的会覆盖前面的):
java·spring boot·后端