codis介绍
    Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说,
    连接到 Codis Proxy 和连接原生的 Redis Server 没有明显的区别 (有一些命令不支持),
    上层应用可以像使用单机的 Redis 一样使用, Codis 底层会处理请求的转发, 不停机的数据迁移等工作,
    所有后边的一切事情, 对于前面的客户端来说是透明的,
    可以简单的认为后边连接的是一个内存无限大的 Redis 服务,当然,
    前段时间redis官方的3.0出了稳定版,3.0支持集群功能,codis的实现原理和3.0的集群功能差不多
    ,我了解的现在美团、阿里已经用了3.0的集群功能了,我们这边的业务主要是php,
    3.0集群的sdk目前貌似还没有支持php语言的,
    大家谁的php应用上了3.0集群,请联系我,我去取经,
    有关redis常见的集群技术,请移步到 @萧田国 萧老师的infoq专栏Redis集群技术及Codis实践
    codis架构
    10.105.67.119 ZooKeeper-node1
    10.105.78.46 ZooKeeper-node2
    10.237.236.73 ZooKeeper-node3
    10.105.78.57 codis-config codis-proxy
    10.105.33.226 codis-proxy
    10.237.164.111 codis server
    6379 6380 group1
    6381 6382 group2
    6383 6384 group3

    zookeeper机器部署
    ZooKeeper-node1:
    vim /data/zookeeper/zookeeper-3.4.6/conf/zoo.cfg ##撰写zk的配置文件
    maxClientCnxns=50 #这里我在实际测试的时候50 zookeeper会卡住,所以我调成了500
    tickTime=2000
    initLimit=10
    syncLimit=5
    dataDir=/data/zookeeper/
    clientPort=2181
    server.1=ZooKeeper-node1:2888:3888
    server.2=ZooKeeper-node2:2888:3888
    server.3=ZooKeeper-node3:2888:3888
    mkdir /data/zookeeper/ ##创建zk的datadir目录
    echo “1” >/data/zookeeper/myid ##生成ID,这里需要注意, myid对应的zoo.cfg的server.ID,比如ZooKeeper-node1对应的myid应该是1
    /data/zookeeper/zookeeper-3.4.6/bin/zkServer.sh start ## 服务启动
    ZooKeeper-node2:
    vim /data/zookeeper/zookeeper-3.4.6/conf/zoo.cfg ##撰写zk的配置文件
    maxClientCnxns=50
    tickTime=2000
    initLimit=10
    syncLimit=5
    dataDir=/data/zookeeper/
    clientPort=2181
    server.1=ZooKeeper-node1:2888:3888
    server.2=ZooKeeper-node2:2888:3888
    server.3=ZooKeeper-node3:2888:3888
    mkdir /data/zookeeper/
    echo “2” >/data/zookeeper/myid
    /data/zookeeper/zookeeper-3.4.6/bin/zkServer.sh start
    ZooKeeper-node3:
    vim /data/zookeeper/zookeeper-3.4.6/conf/zoo.cfg ##撰写zk的配置文件
    maxClientCnxns=50
    tickTime=2000
    initLimit=10
    syncLimit=5
    dataDir=/data/zookeeper/
    clientPort=2181
    server.1=ZooKeeper-node1:2888:3888
    server.2=ZooKeeper-node2:2888:3888
    server.3=ZooKeeper-node3:2888:3888
    mkdir /data/zookeeper/
    echo “3” >/data/zookeeper/myid
    /data/zookeeper/zookeeper-3.4.6/bin/zkServer.sh start
    codis-config codis-proxy codis-server所在机器部署
    wget https://storage.googleapis.com/golang/go1.4.1.linux-amd64.tar.gz —no-check-certificate
    tar -zxvf go1.4.1.linux-amd64.tar.gz
    mv go /usr/local/
    cd /usr/local/go/src/
    bash all.bash
    cat >> ~/.bashrc << _bashrc_export
    export GOROOT=/usr/local/go
    export PATH=\$PATH:\$GOROOT/bin
    export GOARCH=amd64
    export GOOS=linux
    _bashrc_export
    source ~/.bashrc
    mkdir /data/go
    export GOPATH=/data/go
    yum -y install git
    /usr/local/go/bin/go get github.com/wandoulabs/codis 这个会报错安装git 然后还会报错不用管
    cd /data/go/src/github.com/wandoulabs/codis/
    rm -rf
    wget -c https://github.com/CodisLabs/codis/archive/release1.9.zip
    unzip release1.9.zip
    mv codis-release1.9/
    .
    vim bootstrap.sh 加入
    go get -u github.com/xiam/resp
    然后运行
    sh -x bootstrap.sh
    make gotest
    ===========================以上步骤需要在codis所有节点都运行===================================
    启动 dashboard(codis-config上操作)
    cat /etc/codis/config_10.ini ##撰写配置文件
    zk=ZooKeeper-node1:2181,ZooKeeper-node2:2181,ZooKeeper-node3:2181
    product=zh_news
    proxy_id=codis-proxy_10
    net_timeout=5000
    proto=tcp4
    dashboard_addr=10.105.78.57:18087
    coordinator=zookeeper
    cd /data/go/src/github.com/wandoulabs/codis/ && ./bin/codis-config -c /etc/codis/config_10.ini dashboard &
    配置codis-proxy集群10.105.78.57 操作
    mkdir -p /etc/codis/
    vim /etc/codis/config_10.ini
    zk=10.105.67.119:2181,10.105.78.46:2181,10.237.236.73:2181
    product=zh_news
    proxy_id=codis-proxy_10
    net_timeout=5000
    proto=tcp4
    dashboard_addr=10.105.78.57:18087
    coordinator=zookeeper
    初始化 slots (codis-config上操作)
    cd /data/go/src/github.com/wandoulabs/codis/ && ./bin/codis-config -c /etc/codis/config_10.ini slot init
    配置codis-proxy集群10.105.33.226 操作
    mkdir -p /etc/codis/
    vim /etc/codis/config_49.ini
    zk=10.105.67.119:2181,10.105.78.46:2181,10.237.236.73:2181
    product=zh_news
    proxy_id=codis-proxy_49
    net_timeout=5000
    proto=tcp4
    dashboard_addr=10.105.78.57:18087
    coordinator=zookeeper
    启动 Codis Redis Server
    cd /data/go/src/github.com/wandoulabs/codis/
    ./bin/codis-server /data/codis_server/conf/6379.conf
    ./bin/codis-server /data/codis_server/conf/6380.conf
    ./bin/codis-server /data/codis_server/conf/6381.conf
    ./bin/codis-server /data/codis_server/conf/6382.conf
    ./bin/codis-server /data/codis_server/conf/6383.conf
    ./bin/codis-server /data/codis_server/conf/6384.conf
    6379.conf
    daemonize yes
    pidfile /var/run/redis_6379.pid
    port 6379
    tcp-backlog 511
    timeout 300
    tcp-keepalive 0
    loglevel notice
    logfile “/data/codis_server/logs/redis_6379.log”
    databases 16
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename 6379.rdb
    dir /data/codis_server/data
    slave-serve-stale-data yes
    repl-disable-tcp-nodelay no
    slave-priority 100
    maxclients 10000
    maxmemory 3gb
    maxmemory-policy allkeys-lru
    appendonly yes
    appendfilename “6379_appendonly.aof”
    appendfsync everysec
    no-appendfsync-on-rewrite no
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb
    lua-time-limit 5000
    slowlog-log-slower-than 10000
    slowlog-max-len 128
    latency-monitor-threshold 0
    notify-keyspace-events “”
    hash-max-ziplist-entries 512
    hash-max-ziplist-value 64
    list-max-ziplist-entries 512
    list-max-ziplist-value 64
    set-max-intset-entries 512
    zset-max-ziplist-entries 128
    zset-max-ziplist-value 64
    hll-sparse-max-bytes 3000
    activerehashing yes
    client-output-buffer-limit normal 0 0 0
    client-output-buffer-limit slave 256mb 64mb 60
    client-output-buffer-limit pubsub 32mb 8mb 60
    hz 10
    aof-rewrite-incremental-fsync yes
    在codis config机器中添加 Redis Server Group
    ./bin/codis-config -c /etc/codis/config_10.ini server add 1 10.237.164.111:6379 master
    ./bin/codis-config -c /etc/codis/config_10.ini server add 1 10.237.164.111:6380 slave
    ./bin/codis-config -c /etc/codis/config_10.ini server add 2 10.237.164.111:6381 master
    ./bin/codis-config -c /etc/codis/config_10.ini server add 2 10.237.164.111:6382 slave
    ./bin/codis-config -c /etc/codis/config_10.ini server add 3 10.237.164.111:6383 master
    ./bin/codis-config -c /etc/codis/config_10.ini server add 3 10.237.164.111:6384 slave
    设置 server group 服务的 slot (codis config操作)
    cd /data/go/src/github.com/wandoulabs/codis/
    ./bin/codis-config -c /etc/codis/config_10.ini slot range-set 0 300 1 online
    ./bin/codis-config -c /etc/codis/config_10.ini slot range-set 301 700 2 online
    ./bin/codis-config -c /etc/codis/config_10.ini slot range-set 701 1023 3 online
    设置 server group 服务的 slot 范围 Codis 采用 Pre-sharding 的技术来实现数据的分片,
    默认分成 1024 个 slots (0-1023), 对于每个key来说,
    通过以下公式确定所属的 Slot Id : SlotId = crc32(key) % 1024 每一个 slot
    都会有一个特定的 server group id 来表示这个 slot
    的数据由哪个 server group 来提供.(codis-config上操作)
    启动 codis-proxy (codis-proxy上操作)
    10.105.78.57操作:
    cd /data/go/src/github.com/wandoulabs/codis/
    ./bin/codis-proxy -c /etc/codis/config_10.ini -L /data/logs/codis-proxy_10.log —cpu=4 —addr=0.0.0.0:19000 —http-addr=0.0.0.0:11000 &
    10.105.33.226操作
    cd /data/go/src/github.com/wandoulabs/codis/
    ./bin/codis-proxy -c /etc/codis/config_49.ini -L /data/logs/codis-proxy_49.log —cpu=4 —addr=0.0.0.0:19000 —http-addr=0.0.0.0:11000 &
    codis-server的HA
    codis-ha实现codis-server的主从切换,
    codis-server主库挂了会提升一个从库为主库,从库挂了会设置这个从库从集群下线
    export GOPATH=/data/go
    /usr/local/go/bin/go get github.com/ngaut/codis-ha
    cd /data/go/src/github.com/ngaut/codis-ha
    go build
    cp codis-ha /data/go/src/github.com/wandoulabs/codis/bin/
    使用方法:
    /data/go/src/github.com/wandoulabs/codis/bin/codis-ha —codis-config=10.105.78.57:18087 —productName=zh_news &
    使用supervisord管理codis-ha进程
    yum install python-setuptools
    easy_install supervisor
    或者yum -y install supervisord
    /etc/supervisord.conf中添加如下内容:
    [program:codis-ha]
    autorestart = True
    stopwaitsecs = 10
    startsecs = 1
    stopsignal = QUIT
    command = /data/go/src/github.com/wandoulabs/codis/bin/codis-ha —codis-config=10.105.78.57:18087 —productName=zh_news
    user = root
    startretries = 3
    autostart = True
    exitcodes = 0,2
    [supervisord]
    /etc/init.d/supervisord start
    chkconfig supervisord on
    或者使用命令:
    cd /root
    cp /etc/supervisord.conf .
    supervisord -c /etc/supervisord.conf

    一、概要
    1、折腾codis集群已经快两个月了,感谢一直以来codis的作者刘奇和黄东旭的耐心支持,在这里给你们点个赞,现在我司已经有一个业务跑在了codis集群上,目前只是切了整个业务的10%的量,预计下周会全量切到codis上,这个时候大家肯定特别想知道codis稳定吗?有没有什么bug啊,你想知道的也是我想知道的,搞起吧,用了才知道,反正目前我们这没发现啥问题,一些小的问题已经及时联系作者改掉了,好吧,不扯淡了,写这篇文章的目的是帮助想了解codis的初学者快速部署(官方的部署文档对应运维知识弱一点的童鞋看来还是有点费力)还有就是给自己做一个备录以便后期集群的部署。
    2、Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis Proxy 和连接原生的 Redis Server 没有明显的区别 (有一些命令不支持), 上层应用可以像使用单机的 Redis 一样使用, Codis 底层会处理请求的转发, 不停机的数据迁移等工作, 所有后边的一切事情, 对于前面的客户端来说是透明的, 可以简单的认为后边连接的是一个内存无限大的 Redis 服务,当然,前段时间redis官方的3.0出了稳定版,3.0支持集群功能,codis的实现原理和3.0的集群功能差不多,我了解的现在美团、阿里已经用了3.0的集群功能了,我们这边的业务主要是php,3.0集群的sdk目前貌似还没有支持php语言的,大家谁的php应用上了3.0集群,请联系我,我去取经,有关redis常见的集群技术,请移步到 @萧田国 萧老师的infoq专栏Redis集群技术及Codis实践
    二、架构

    三、角色分批
    zookeeper集群:10.10.0.4710.10.0.4810.10.1.76codis-config、codis-ha:10.10.32.10:18087codis-proxy:10.10.32.10:1900010.10.32.49:19000codis-server:10.10.32.42:6379、10.10.32.43:6380(主、从)10.10.32.43:6379、10.10.32.44:6380(主、从)10.10.32.44:6379、10.10.32.42:6380(主、从)
    四、部署
    1、安装zookeeper
    yum -y install zookeeper jdk ##安装服务
    vim /etc/hosts ##添加host10.10.0.47 ZooKeeper-node110.10.0.48 ZooKeeper-node210.10.1.76 ZooKeeper-node3
    vim /etc/zookeeper/conf/zoo.cfg ##撰写zk的配置文件maxClientCnxns=50tickTime=2000initLimit=10syncLimit=5dataDir=/data/zookeeper/clientPort=2181server.1=ZooKeeper-node1:2888:3888server.2=ZooKeeper-node2:2888:3888server.3=ZooKeeper-node3:2888:3888
    mkdir /data/zookeeper/ ##创建zk的datadir目录echo”2”>/data/zookeeper/myid ##生成ID,这里需要注意, myid对应的zoo.cfg的server.ID,比如ZooKeeper-node2对应的myid应该是2/usr/lib/zookeeper/bin/zkServer.sh start ## 服务启动
    2、go安装(codis是go语言写的,所以那些机器需要安装你懂得)
    wget https://storage.googleapis.com/golang/go1.4.1.linux-amd64.tar.gztar -zxvf go1.4.1.linux-amd64.tar.gzmv go /usr/local/cd /usr/local/go/src/bash all.bashcat>> ~/.bashrc <<_bashrc_exportexport GOROOT=/usr/local/goexport PATH=\$PATH:\$GOROOT/binexport GOARCH=amd64export GOOS=linux_bashrc_exportsource ~/.bashrc
    3、下载并编译codis(codis-config、codis-proxy、codis-server所在的机器)
    mkdir /data/goexport GOPATH=/data/go/usr/local/go/bin/go get github.com/wandoulabs/codiscd /data/go/src/github.com/wandoulabs/codis/./bootstrap.shmake gotest
    五、服务启动及初始化集群
    1、启动 dashboard(codis-config上操作)
    cat /etc/codis/config_10.ini ##撰写配置文件zk=10.10.0.47:2181,10.10.0.48:2181,10.10.1.76:2181product=zh_newsproxy_id=codis-proxy_10net_timeout=5000proto=tcp4dashboard_addr=10.10.32.10:18087
    cd /data/go/src/github.com/wandoulabs/codis/ && ./bin/codis-config -c /etc/codis/config_10.ini dashboard &
    2、初始化 slots (codis-config上操作)
    cd /data/go/src/github.com/wandoulabs/codis/ && ./bin/codis-config -c /etc/codis/config_10.ini slot init
    3、启动 Codis Redis , 和官方的Redis Server参数一样(codis-server上操作)
    cd /data/go/src/github.com/wandoulabs/codis/ && ./bin/codis-server /etc/redis_6379.conf &
    4、添加 Redis Server Group , 每一个 Server Group 作为一个 Redis 服务器组存在, 只允许有一个 master, 可以有多个 slave, group id 仅支持大于等于1的整数(codis-config上操作)
    cd /data/go/src/github.com/wandoulabs/codis/./bin/codis-config -c /etc/codis/config_10.ini server add 1 10.10.32.42:6379 master./bin/codis-config -c /etc/codis/config_10.ini server add 1 10.10.32.43:6380 slave./bin/codis-config -c /etc/codis/config_10.ini server add 2 10.10.32.43:6379 master./bin/codis-config -c /etc/codis/config_10.ini server add 2 10.10.32.44:6380 slave./bin/codis-config -c /etc/codis/config_10.ini server add 3 10.10.32.44:6379 master./bin/codis-config -c /etc/codis/config_10.ini server add 3 10.10.32.42:6380 slave
    5、设置 server group 服务的 slot 范围 Codis 采用 Pre-sharding 的技术来实现数据的分片, 默认分成 1024 个 slots (0-1023), 对于每个key来说, 通过以下公式确定所属的 Slot Id : SlotId = crc32(key) % 1024 每一个 slot 都会有一个特定的 server group id 来表示这个 slot 的数据由哪个 server group 来提供.(codis-config上操作)
    cd /data/go/src/github.com/wandoulabs/codis/./bin/codis-config -c /etc/codis/config_10.ini slot range-set 0 300 1 online./bin/codis-config -c /etc/codis/config_10.ini slot range-set 301 700 2 online./bin/codis-config -c /etc/codis/config_10.ini slot range-set 701 1023 3 online
    6、启动 codis-proxy (codis-proxy上操作)
    cat /etc/codis/config_10.ini ##撰写配置文件zk=10.10.0.47:2181,10.10.0.48:2181,10.10.1.76:2181product=zh_newsproxy_id=codis-proxy_10 ##10.10.32.49上改成codis-proxy_49,多个proxy,proxy_id 需要唯一net_timeout=5000proto=tcp4dashboard_addr=10.10.32.10:18087
    cd /data/go/src/github.com/wandoulabs/codis/ && ./bin/codis-proxy -c /etc/codis/config_10.ini -L /data/log/codis-proxy_10.log —cpu=4 —addr=0.0.0.0:19000 —http-addr=0.0.0.0:11000 &cd /data/go/src/github.com/wandoulabs/codis/ && ./bin/codis-proxy -c /etc/codis/config_49.ini -L /data/log/codis-proxy_49.log —cpu=4 —addr=0.0.0.0:19000 —http-addr=0.0.0.0:11000 &
    OK,整个集群已经搭建成功了,截图给你们show show

    六、codis-server的HA
    codis-ha实现codis-server的主从切换,codis-server主库挂了会提升一个从库为主库,从库挂了会设置这个从库从集群下线
    1、安装
    export GOPATH=/data/go/usr/local/go/bin/go get github.com/ngaut/codis-hacd /data/go/src/github.com/ngaut/codis-hago buildcp codis-ha /data/go/src/github.com/wandoulabs/codis/bin/使用方法:codis-ha —codis-config=dashboard地址:18087 —productName=集群项目名称
    2、使用supervisord管理codis-ha进程
    yum -y install supervisord
    /etc/supervisord.conf中添加如下内容:[program:codis-ha]autorestart = Truestopwaitsecs = 10startsecs = 1stopsignal = QUITcommand= /data/go/src/github.com/wandoulabs/codis/bin/codis-ha —codis-config=10.10.32.17:18087 —productName=zh_newsuser = rootstartretries = 3autostart = Trueexitcodes = 0,2
    3、启动supervisord服务
    /etc/init.d/supervisord startchkconfig supervisord on
    此时,ps -ef |grep codis-ha 你回发现codis-ha进程已经启动,这个时候你去停掉一个codis-server的master,看看slave会不会提升为master呢

    七、关于监控
    关于整个codis集群的监控,我们这边用的是zabbix,监控的指标比较简单,所以这块大家有什么好的建议多给我提提哈
    zookeeper:监控各个节点的端口联通性(以后想着把进程也监控上)
    codis-proxy:监控了端口的联通性,这个监控远远不够呀
    codis-server:监控了内存使用率、连接数、联通性
    codis-ha:监控进程
    dashboard:监控端口联通性

    八、使用过程中遇到的问题
    1、codis-proxy的日志切割,codis-proxy的默认日志级别是info,日志量很大,我们这边每天产生50多G日志,目前codis-proxy还不支持热重启,想修改启动参数还是比较麻烦的,日志切割推荐用logrotate
    2、codis-proxy的监听地址默认没有具体ipv4,也就是codis-proxy启动之后没有0.0.0.0:19000这样的监听,这样会导致的问题就是前端lvs没有办法负载均衡codis-proxy,不能转发请求过,这个问题已联系作者处理了,在codis-proxy启动的配置文件中加上proto=tcp4这个参数就支持监听ipv4了
    3、添加 Redis Server Group的时候,非codis-server(原生的redis)竟然也能加入到codis集群里面,在redis和codis-server共存在一个物理机上的清楚,很容易加错,希望能有个验证,非codis-server不能加入到codis集群
    4、codis集群内部通讯是通过主机名的,如果主机名没有做域名解析那dashboard是通过主机名访问不到proxy的http-addr地址的,这会导致从web界面上看不到OP/s的数据,至于还有没有其他问题,目前我这边还没有发现,建议内部通讯直接用内网IP
    PS:我已建立一个管理codis的QQ群,对codis感兴趣的可以加入一起交流,群号: 183613045