天天看点

利用Docker安装运行Codis

最近打算对缓存中间进行专题性学习,之前使用过Redis Sentinal,后来认识到Codis,对Codis产生感兴趣,于是便有了下面的安装运行总结。

什么是Codis

目前基于Redis集群的方案有三种,第一种是Redis Sentinal,第二种是Redis Cluster,第三种是豌豆荚的Codis。

Redis Sentinal搭建简单,不过受Redis容量限制,普通应用个人觉得已经足够了;本来想分析一下Redis Cluster,不过由于个人没用过,不好说;至于Codis,第一次听说是大概一年前去唯品会面试的时候(原谅我当时的孤陋寡闻),后来就一直留意这个东西,对Codis的动态扩容缩容以及监控页面很甘兴趣,最后狠下心来搭一套起来玩玩。

Twemproxy与Codis

说到Codis不得不提Twemproxy,Twemproxy是twitter开发的redis代理,能够实现数据分片,通过keeplived来实现高可用。不过Twemproxy也有自己的一些痛点:

  • 无法平滑地扩容或缩容

    由于Twemproxy是静态sharding,当业务需要对redis进行扩容或缩容时会导致大量数据不能命中,需要resharding,这对缓存强依赖的应用来说比较致命。

  • 修改配置需要重启

    这个就不用多解释了…

  • 不可运维,没有Dashboard

    这点对运维人员比较痛苦,不能通过控制台对集群进行监控配置

相比而言,Codis比较好地克服了上面的缺点。

Codis概览

首先看看官网上Codis的架构图

利用Docker安装运行Codis

下面是官方解释:

Codis 3.x 由以下组件组成:

Codis Server:基于 redis-2.8.21 分支开发。增加了额外的数据结构,以支持 slot 有关的操作以及数据迁移指令。具体的修改可以参考文档 redis 的修改。

Codis Proxy:客户端连接的 Redis 代理服务, 实现了 Redis 协议。 除部分命令不支持以外(不支持的命令列表),表现的和原生的 Redis 没有区别(就像 Twemproxy)。

对于同一个业务集群而言,可以同时部署多个 codis-proxy 实例;

不同 codis-proxy 之间由 codis-dashboard 保证状态同步。

Codis Dashboard:集群管理工具,支持 codis-proxy、codis-server 的添加、删除,以及据迁移等操作。在集群状态发生改变时,codis-dashboard 维护集群下所有 codis-proxy 的状态的一致性。

对于同一个业务集群而言,同一个时刻 codis-dashboard 只能有 0个或者1个;

所有对集群的修改都必须通过 codis-dashboard 完成。

Codis Admin:集群管理的命令行工具。

可用于控制 codis-proxy、codis-dashboard 状态以及访问外部存储。

Codis FE:集群管理界面。

多个集群实例共享可以共享同一个前端展示页面;

通过配置文件管理后端 codis-dashboard 列表,配置文件可自动更新。

Codis HA:为集群提供高可用。

依赖 codis-dashboard 实例,自动抓取集群各个组件的状态;

会根据当前集群状态自动生成主从切换策略,并在需要时通过 codis-dashboard 完成主从切换。

Storage:为集群状态提供外部存储。

对Codis架构有大概了解之后,下面我们就开始利用Docker来搭建Codis

利用Docker搭建Codis

首先上一幅描述各个组件之间连接关系的图

利用Docker安装运行Codis

利用docker发布服务的时候,需要添加

--host-admin

来指定服务对外的访问地址。

如果不这样做的话,dashboard将不能正确获取到proxy对外的代理和管理端口。例如容器内proxy的管理端口是19000,不添加–host-admin情况下,dashboard会以为proxy的管理端口就是19000,此时是访问不通的(docker真正对外的地址是29000)。

1.准备Dockerfile

FROM golang:.

RUN apt-get update
RUN apt-get install -y vim bash golang
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*

ENV GOPATH /gopath
ENV CODISLABS ${GOPATH}/src/github.com/CodisLabs  #存放Codis源码目录
ENV CODIS  ${CODISLABS}/codis
ENV GOX    ${GOPATH}/src/golang.org/x
ENV PATH   ${GOPATH}/bin:${PATH}:${CODIS}/bin

WORKDIR ${GOX}
RUN git clone https://github.com/golang/net.git  #获取gonet源码

WORKDIR ${CODISLABS}
RUN git clone https://github.com/CodisLabs/codis.git #获取codis源码

WORKDIR ${CODIS}
RUN git checkout release3.  #基于codis3.0release版本构建

WORKDIR ${CODIS}
RUN make

WORKDIR /codis
           

参考:https://github.com/CodisLabs/codis/blob/release3.0/Dockerfile

Dockerfile是参考官方的例子作了一点修改

首先是添加了环节变量CODISLABS,这个目录的作用是存放Codis的源码。

然后添加 git clone https://github.com/golang/net.git 和 git clone https://github.com/CodisLabs/codis.git,获取Codis和Go依赖的源码

最后进入CODIS的目录进行编译,编译完成后把工作目录设置为/codis (接下来执行的命令默认会在/coids下执行)

2.在Dockerfile所在目录下构建docker image

长时间的耐心等待… done!

3.构建docker启动脚本

参考https://github.com/CodisLabs/codis/blob/release3.0/scripts/docker.sh

#!/bin/bash
#获取宿主机ip地址
hostip=`ifconfig enp0s3 | grep "inet " | awk -F " " '{print $2}'`

if [ "x$hostip" == "x" ]; then
    echo "cann't resolve host ip address"
    exit 
fi

mkdir -p log

case "$1" in
dashboard) #启动dashboard
    docker rm -f      "Codis-D28080" &> /dev/null
    docker run --name "Codis-D28080" -d \
         -v `realpath config/dashboard.toml`:/codis/dashboard.toml \
                    -v `realpath log`:/codis/log \
        -p : \
         --privileged=true \
        lzw2006/codis \
        codis-dashboard -l /codis/log/dashboard.log -c /codis/dashboard.toml --host-admin ${hostip}:
    ;;

proxy)  #启动proxy
    docker rm -f      "Codis-P29000" &> /dev/null
    docker run --name "Codis-P29000" -d \
        --read-only -v `realpath config/proxy.toml`:/codis/proxy.toml \
                    -v `realpath log`:/codis/log \
        -p : -p : \
    --privileged=true \
        lzw2006/codis \
        codis-proxy -l /codis/log/proxy.log -c /codis/proxy.toml --host-admin ${hostip}: --host-proxy ${hostip}:
    ;;

server) #启动4个redis实例
    for ((i=;i<;i++)); do
        let port="26379 + i"
        docker rm -f      "Codis-S${port}" &> /dev/null
        docker run --name "Codis-S${port}" -d \
            -v `realpath log`:/codis/log \
            -p $port: \
        --privileged=true \
            lzw2006/codis \
            codis-server --logfile /codis/log/${port}.log
    done
    ;;

fe) #启动监控页面
    docker rm -f      "Codis-F8080" &> /dev/null
    docker run --name "Codis-F8080" -d \
         -v `realpath log`:/codis/log \
         -v `realpath config/codis.json`:/codis/codis.json \
         -p : \
     -privileged=true \
     lzw2006/codis \
      /gopath/src/github.com/CodisLabs/codis/bin/codis-fe -l /codis/log/fe.log --dashboard-list=/codis/codis.json --listen=.:
    ;;


cleanup)
    docker rm -f      "Codis-D28080" &> /dev/null
    docker rm -f      "Codis-P29000" &> /dev/null
    for ((i=;i<;i++)); do
        let port="26379 + i"
        docker rm -f      "Codis-S${port}" &> /dev/null
    done
    ;;

*)
    echo "wrong argument(s)"
    ;;

esac
           

利用这脚本能启动dashboard、 proxy、fe以及redis-server。

4.准备配置文件

建立config文件夹,把dashboard.toml、codis.json和proxy.toml复制到config文件夹下。

配置文件都是可以通过Codis自带的命令生成,例如dashboard.toml可以通过

./bin/codis-dashboard –default-config | tee dashboard.toml

生成

dashboard.toml

##################################################
#                                                #
#                  Codis-Dashboard               #
#                                                #
##################################################

# Set Coordinator, only accept "zookeeper" & "etcd"
coordinator_name = "zookeeper"
coordinator_addr = "10.100.5.74:2181"

# Set Codis Product {Name/Auth}.
product_name = "codis-demo"
product_auth = ""

# Set bind address for admin(rpc), tcp only.
admin_addr = "0.0.0.0:18080"
           

proxy.toml

##################################################
#                                                #
#                  Codis-Proxy                   #
#                                                #
##################################################

# Set Codis Product {Name/Auth}.
product_name = "codis-demo"
product_auth = ""

# Set bind address for admin(rpc), tcp only.
admin_addr = "0.0.0.0:19000"

# Set bind address for proxy, proto_type can be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
proto_type = "tcp4"
proxy_addr = "0.0.0.0:11080"

# Set jodis address & session timeout.
jodis_addr = ""
jodis_timeout = 

# Proxy will ping-pong backend redis periodly to keep-alive
backend_ping_period = 

# If there is no request from client for a long time, the connection will be droped. Set  to disable.
session_max_timeout = 

# Buffer size for each client connection.
session_max_bufsize = 

# Number of buffered requests for each client connection.
# Make sure this is higher than the max number of requests for each pipeline request, or your client may be blocked.
session_max_pipeline = 

# Set period between keep alives. Set  to disable.
session_keepalive_period = 
           

codis.json

[
    {
        "name": "codis-demo",
        "dashboard": "10.100.5.74:28080"
    }
]
           

5.启动zookeeper

怎样安装和启动zookeeper请自行百度

6.启动dashboard

./docker.sh dashboard
           
利用Docker安装运行Codis

访问宿主机http://10.100.5.74:28080/topom能成功见到返回的json数据

利用Docker安装运行Codis

7.启动proxy

./docker.sh proxy
           
利用Docker安装运行Codis

访问宿主机 http://10.100.5.74:29000/proxy ,能看到json数据

利用Docker安装运行Codis

8.启动redis

脚本会在本地启动4个redis实例

利用Docker安装运行Codis

9.启动codis-fe

./docker.sh fe
           

访问 http://10.100.5.74:8080/ 能看到下面的页面

利用Docker安装运行Codis

10.在FE上配置proxy,redis server和slot

  • 添加服务器组,并往里面添加redis实例
    利用Docker安装运行Codis
  • 配置slot(初始化slot)
    利用Docker安装运行Codis
  • 添加proxy
    利用Docker安装运行Codis

到这里Codis已经启动起来

接下来就可以使用redis-cli连接codis的proxy,就跟直连redis一样

以上只是展示了一个大概的过程,可能你在安装的时候遇到各种问题,耐心一点就能解决!

另外,Codis是用3.0release版本,请留意!

转发请附上原文链接:http://blog.csdn.net/lzw_2006/article/details/51151364

继续阅读