前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Shell 脚本自动部署 Redis 集群

Shell 脚本自动部署 Redis 集群

作者头像
用户2987604
发布2020-06-15 15:36:11
2K0
发布2020-06-15 15:36:11
举报

我时常需要在云服务器上搭建测试环境,每次入手新的服务器配置集群环境时,跟着笔记敲一遍命令行挺麻烦的。学了 shell 脚本后,我尝试使用脚本在单机服务器上部署 Redis 集群。

安装 Redis 服务器

参照 Redis 主从集群及自启动配置 实现自动安装,首先判断是否已安装,若存在 Redis 服务程序则跳过,否则安装。

代码语言:javascript
复制
# Check redis commandif [ ! -f "/usr/local/bin/redis-server" ]; then  echo "Redis not ready, please install redis firstly!"  echo ""  echo "===== Install redis as follows ====="  wget http://download.redis.io/releases/redis-5.0.7.tar.gz -P /usr/local/src  cd /usr/local/src/  tar -zxvf redis-5.0.7.tar.gz  cd redis-5.0.7  install GCC if not exists  yum install -y gcc-c++  make MALLOC=libc install
  echo ""  echo "Redis Server Installation Finished!"fi

通过 if[!-f"/usr/local/bin/redis-server"] 判断 server 程序是否存在,若存在则认为 Redis 已安装。

采用源码编译的方式安装 Redis,已指定 5.0.7 版本,防止出现兼容性问题。

生成 Redis 实例的配置文件

常量定义

代码语言:javascript
复制
# ConstantsBASE_DIR=/usr/local/redis-clusterPORTS=`seq 7000 7005`START_UP=$BASE_DIR/startup.sh
  • BASE_DIR 为集群配置 directory;
  • PORTS 为集群在本地所占用的端口列表, seq70007005 生成 7000-7005 的整数数组;
  • START_UP 为集群实例启动脚本,集群需要启动 6 个 Redis 实例,使用脚本简化操作。

准备工作

代码语言:javascript
复制
# 创建工作目录,在工作目录下进行后续操作mkdir -p $BASE_DIRcd $BASE_DIR
# 准备集群实例启动脚本,在每次实例配置循环时将启动命令追加到脚本中echo "#!/bin/bash" > $START_UPservers=for port in $PORTS; do   # 设置每个实例的工作目录, data为数据存放目录  mkdir -p $BASE_DIR/$port/data  # 生成单个实例的配置文件  generate_instance_conf $port  # 追加实例启动命令到启动脚本  echo "/usr/local/bin/redis-server $BASE_DIR/$port/redis.conf" >> $START_UP  # 记录所有的实例位置,用于之后的集群启动  servers="$servers 127.0.0.1:$port "done

配置文件

每个实例的配置文件相似,只是端口号和工作目录不同。还有一点需要注意,要想可以从其它外部主机访问此主机上的 Redis 集群,需要将实例的集群地址设置为主机的外网地址,因此需要用户手动输入主机外网地址。

使用 shell 实现外网地址获取的交互模式:

代码语言:javascript
复制
# User custom settingecho -n "Enter your host's public address(default 127.0.0.1):"read cluster_address

将实例配置依次写入 redis.conf 中:

代码语言:javascript
复制
# generate configuration filesfunction generate_instance_conf() {  echo "configuring server $1"
  # clean conf file  echo "" > $1/redis.conf  # write conf  echo "port $1" >> $1/redis.conf  echo "bind 0.0.0.0" >> $1/redis.conf  echo "dir $BASE_DIR/$port/data" >> $1/redis.conf  echo "cluster-enabled yes" >> $1/redis.conf  echo "cluster-config-file nodes-$1.conf" >> $1/redis.conf  echo "cluster-node-timeout 5000" >> $1/redis.conf  if [ -n "$cluster_address" ]; then     echo "cluster-announce-ip $cluster_address" >> $1/redis.conf  else     echo "cluster-announce-ip 127.0.0.1" >> $1/redis.conf  fi  echo "appendonly yes" >> $1/redis.conf  echo "daemonize yes" >> $1/redis.conf}chmod +x $START_UP

如上步骤完成后,集群工作目录如下:

代码语言:javascript
复制
drwxr-xr-x 3 root root 4096 Apr 19 11:07 7000drwxr-xr-x 3 root root 4096 Apr 19 11:07 7001drwxr-xr-x 3 root root 4096 Apr 19 11:07 7002drwxr-xr-x 3 root root 4096 Apr 19 11:07 7003drwxr-xr-x 3 root root 4096 Apr 19 11:07 7004drwxr-xr-x 3 root root 4096 Apr 19 11:07 7005-rwxr-xr-x 1 root root  426 Apr 19 11:07 startup.sh

启动实例并建立集群

启动 Redis 服务实例

代码语言:javascript
复制
# startup instancesecho "starting servers..."$START_UPsleep 5secho "servers ready!"

执行启动脚本,启动 6 个 Redis 实例,并保持休眠 5 秒,等待集群启动完成,执行结果如下:

代码语言:javascript
复制
starting servers...27764:C 19 Apr 2020 11:07:58.874 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo27764:C 19 Apr 2020 11:07:58.874 # Redis version=5.0.7, ..27764:C 19 Apr 2020 11:07:58.874 # Configuration loaded...27777:C 19 Apr 2020 11:07:58.885 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo27777:C 19 Apr 2020 11:07:58.885 # Redis version=5.0.7, ..27777:C 19 Apr 2020 11:07:58.885 # Configuration loadedservers ready!     

建立集群

代码语言:javascript
复制
# create clusterecho "configuring cluster..."/usr/local/bin/redis-cli --cluster create $servers --cluster-replicas 1echo "configured!"

使用 redis-cli 建立集群,指定所要包含实例的 host 和 port,$servers 中就是这些信息。

代码语言:javascript
复制
configuring cluster...>>> Performing hash slots allocation on 6 nodes...Master[0] -> Slots 0 - 5460Master[1] -> Slots 5461 - 10922Master[2] -> Slots 10923 - 16383...Can I set the above configuration? (type 'yes' to accept): yes...[OK] All nodes agree about slots configuration.>>> Check for open slots...>>> Check slots coverage...[OK] All 16384 slots covered.configured!

集群建立时需要用户手动确认槽数划分,输入 yes 即可。

至此集群部署完成,下面配置集群开机自启动。

systemd 自启动

使用 systemd 配置 Redis 集群启动服务,首先配置 service 文件:

代码语言:javascript
复制
# generate redis-cluster service filecat << EOT > $BASE_DIR/redis-cluster.service[Unit]Description=Redis 5.0 Cluster ServiceAfter=network.target
[Service]Type=forkingExecStart=/usr/local/redis-cluster/startup.sh
[Install]WantedBy=default.targetEOT

cat<<EOT>$BASE_DIR/redis-cluster.service 表示向 redis-cluster.service 文件中覆盖一段内容,内容为下一行至 EOT 之间的内容。

代码语言:javascript
复制
# create serviceecho "Creating redis cluster service..."# 在 systemd 文件夹下创建 service 的软连接并启动 redis 集群服务ln -s $BASE_DIR/$SERVICE /etc/systemd/system/$SERVICEsudo systemctl daemon-reload && sudo systemctl enable $SERVICE && sudo systemctl start $SERVICE

集群删除

使用 --remove 参数执行集群删除操作:

代码语言:javascript
复制
# Remove redis clusterfunction remove_cluster() {  # 终止各 Reids 实例进程  ps -ef | grep redis-server | grep cluster | awk '{print $2}' | xargs kill -9  # 移除 systemd 服务  systemctl disable redis-cluster.service  # 移除工作目录(配置文件和数据)  if [ -d $BASE_DIR ]; then    rm -rf $BASE_DIR  fi}
if [ "$1" = "--remove" ]; then  remove_cluster  exit 0fi

通过过滤器 grep 和流式编辑器 awk 查询到 Redis 实例的 pid,使用 kill 命令结束进程。

其中 awk'{print $2}'awk-F' ''{print $2}' 的缩写, -F 表示分隔符参数,默认为空格, `awk -F ' ' 将如下内容分割为数组:

代码语言:javascript
复制
root 27765 1 0 11:07 ? 00:00:03 /usr/local/bin/redis-server 0.0.0.0:7000 [cluster]

{print$2} 表述输出第 2 个元素,$0 表述输出整行。

完整的 shell

代码语言:javascript
复制
#!/bin/bash
BASE_DIR=/usr/local/redis-cluster
PORTS=`seq 7000 7005`
START_UP=$BASE_DIR/startup.sh
SERVICE=redis-cluster.service
# Remove redis clusterfunction remove_cluster() {  # kill redis servers  ps -ef | grep redis-server | grep cluster | awk '{print $2}' | xargs kill -9  # disable systemd  systemctl disable redis-cluster.service  # rm cluster data  if [ -d $BASE_DIR ]; then    rm -rf $BASE_DIR  fi}
if [ "$1" = "--remove" ]; then  remove_cluster  exit 0fi
# Check redis commandif [ ! -f "/usr/local/bin/redis-server" ]; then  echo "Redis not ready, please install redis firstly!"  echo ""  echo "===== Install redis as follows ====="  wget http://download.redis.io/releases/redis-5.0.7.tar.gz -P /usr/local/src  cd /usr/local/src/  tar -zxvf redis-5.0.7.tar.gz  cd redis-5.0.7  install GCC if not exists  yum install -y gcc-c++  make MALLOC=libc install
  echo ""fi
# User custom settingecho -n "Enter your host's public address(default 127.0.0.1):"read cluster_address
# enter work directorymkdir -p $BASE_DIRcd $BASE_DIR
# generate configuration filesfunction generate_instance_conf() {  echo "configuring server $1"
  # clean conf file  echo "" > $1/redis.conf  # write conf  echo "port $1" >> $1/redis.conf  echo "bind 0.0.0.0" >> $1/redis.conf  echo "dir $BASE_DIR/$1/data" >> $1/redis.conf  echo "cluster-enabled yes" >> $1/redis.conf  echo "cluster-config-file nodes-$1.conf" >> $1/redis.conf  echo "cluster-node-timeout 5000" >> $1/redis.conf  if [ -n "$cluster_address" ]; then     echo "cluster-announce-ip $cluster_address" >> $1/redis.conf  else     echo "cluster-announce-ip 127.0.0.1" >> $1/redis.conf  fi  echo "appendonly yes" >> $1/redis.conf  echo "daemonize yes" >> $1/redis.conf}

# mkdir dirs and setup startup.shecho "#!/bin/bash" > $START_UPservers=for port in $PORTS; do   mkdir -p $BASE_DIR/$port/data  # generate conf files  generate_instance_conf $port  #  echo "/usr/local/bin/redis-server $BASE_DIR/$port/redis.conf" >> $START_UP  # servers  servers="$servers 127.0.0.1:$port "done
# startup instanceschmod +x $START_UPecho "starting servers..."$START_UPsleep 5secho "servers ready!"
# create clusterecho "configuring cluster..."/usr/local/bin/redis-cli --cluster create $servers --cluster-replicas 1echo "configured!"
# generate redis-cluster service filecat << EOT > $BASE_DIR/redis-cluster.service[Unit]Description=Redis 5.0 Cluster ServiceAfter=network.target
[Service]Type=forkingExecStart=/usr/local/redis-cluster/startup.sh
[Install]WantedBy=default.targetEOT
# create serviceecho "Creating redis cluster service..."ln -s $BASE_DIR/$SERVICE /etc/systemd/system/$SERVICEsudo systemctl daemon-reload && sudo systemctl enable $SERVICE && sudo systemctl start $SERVICE
# Cluster OKecho ""echo "Completed!"echo ""echo "Test cluster with: /usr/local/bin/redis-cli -h 127.0.0.1 -p 7000"echo ""echo "127.0.0.1:7000>cluster nodes"

脚本下载:http://pic.blackist.top/202004182234_789.sh

参考

https://blackist.org/2020/04/03/redis-cluster-masterandslave/

https://stackoverflow.com/questions/13910087/shell-script-to-capture-process-id-and-kill-it-if-exist

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 董亮亮的开发笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 安装 Redis 服务器
  • 生成 Redis 实例的配置文件
    • 常量定义
      • 准备工作
        • 配置文件
        • 启动实例并建立集群
          • 启动 Redis 服务实例
            • 建立集群
            • systemd 自启动
            • 集群删除
            • 完整的 shell
            • 参考
            相关产品与服务
            云数据库 Redis
            腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档