codis -- redis集群解决方案

一、线上redis集群架构图


haproxy:对client端(qb,uc等)做转发和负载均衡
codis-config:对codis进行管理,并且提供dashboard
codis-proxy:redis的代理,实现了redis协议
codis:即redis服务,基于redis2.8.13开发
zookeeper:管理和协调codis-proxy节点信息
codis-ha:监控codis服务,并在codis服务异常退出时及时将服务拉起
codis-proxy-ha:监控codis-proxy服务,并在codis-proxy服务异常退出时及时将服务拉起
 
线上16台实体机,每台均部署了codis,其中codis-proxy和zookeeper、codis-config、haproxy分开部署。
 
二、codis集群的性能
单台压力机器施压最高可以达到20w OPS。
 
三、codis集群的高可用
持续以13w OPS的压力压测7*24 小时,总的key操作达到900亿,未命中的500个,命中率超过99.99%。
压测期间,codis-proxy出现10次异常退出,codis没有出现任何异常。
===================================================================================

 

线网大部分redis切换到了codis集群

但是在使用过程中有一些限制要求,请大家关注,检查自己的代码是否有问题。
 
线上部分应用已经切到codis(redis)集群,由于codis的特性,有以下几点请帮忙在开发团队内普及:
1、各个应用所使用的key需要命名规范,避免key冲突的情况,因为对于线上所有的应用来说,都使用的是一个redis
2、只能使用db0 的库,其它库均不支持
3、考虑codis本身设计,应尽量避免出现  key小,但是value特别大(>1M)
4、部分命令不支持,不支持的命令列表如下: https://github.com/wandoulabs/codis/blob/master/doc/unsupported_cmds.md
Command Type Command Name
Keys KEYS
  MIGRATE
  MOVE
  OBJECT
  RANDOMKEY
  RENAME
  RENAMENX
  SCAN
   
Strings BITOP
  MSETNX
   
Lists BLPOP
  BRPOP
  BRPOPLPUSH
   
Pub/Sub PSUBSCRIBE
  PUBLISH
  PUNSUBSCRIBE
  SUBSCRIBE
  UNSUBSCRIBE
   
Transactions DISCARD
  EXEC
  MULTI
  UNWATCH
  WATCH
   
Scripting SCRIPT
   
Server BGREWRITEAOF
  BGSAVE
  CLIENT
  CONFIG
  DBSIZE
  DEBUG
  FLUSHALL
  FLUSHDB
  LASTSAVE
  MONITOR
  RESTORE
  SAVE
  SHUTDOWN
  SLAVEOF
  SLOWLOG
  SYNC
  TIME
   
Codis Slot SLOTSCHECK
  SLOTSDEL
  SLOTSINFO
  SLOTSMGRTONE
  SLOTSMGRTSLOT
  SLOTSMGRTTAGONE
  SLOTSMGRTTAGSLOT
===================================================================
Redis key的命名规范
 

概述:

为了降低各系统的耦合度,后面redis根据应用域名进行分区存储,各应用使用各自的redis。老的redis保留,兼容老的应用程序。

命名规范:“域:业务:功能:特性”

“域:业务”是必须有的,“功能:特性”是扩展字段

以宝筹项目为例:存储商品id为1的买5交易数据,key为“baochou:trade:buy5:1”;用户还在委托中的单子数量,key为 “baochou:trade:pending:2015-01-26_102661_1”

各应用可以提供一个命名的帮助类,核心方法如下:

//key分隔符

public final static String REDIS_NAMESPACE_SEPARATOR = ":";

//静态key部分

public final static String REDIS_KEY_USER="user:register:id";

 

//动态key生成方法

@Override
public String generateCacheKey(String namespace, Object... keys) {
        StringBuffer out=new StringBuffer();
        out.append(namespace);
        out.append(REDIS_NAMESPACE_SEPARATOR);
        for(int i=0;i<keys.length;i++){
                out.append(keys[i]);
                if(i!=keys.length-1){ 
                        out.append("_“);
              }
        }
        return out.toString();
}

例如:“baochou:trade:pending:2015-01-26_102661_1”,“baochou:trade:pending“即为namespace,”2015-01-26_102661_1“为“日期_用户id_商品id”,整个key描述了“用户某天某个商品的正在委托中的数量” 

目前整理的业务应用:

各业务后面提供单独的redis

  • 后台:backoffice & 前台www & 接口m

  • gamepay & 订单order (目前未用reds)
  • bizorder (微商订单,目前用的qianbao redis)
  • 宝筹:bc  & bcbo 宝筹后台
  • 商品goods & goodsba
  • im
  • leipai
  • 用户user
  • 登陆passport
  • 拍卖paimai & pmba  拍卖后台
  • qhb 抢红包
  • t  有票 & ticketbo 有票后台
  • tpush  有票推送

现在的应用中有同一redis实例中跨应用使用同一key的情况,后面分应用存储以后,坚决杜绝此情况,有跨应用使用的情况,请提供http接口。

各业务redis key查询列表:

各业务自己添加,表头两项:“key名称” “key含义”,例如:

key名称
key含义
baochou:trade:buy5:1 存储商品id为1的买5交易数据
baochou:trade:pending:2015-01-26_102661_1 用户某天某个商品的正在委托中的数量
=====================================================
线上大部分的应用服务使用的redis服务已经切换到了新的codis(基于redis2.8.13开发)集群(除了抢红包和签到所用的redis没有迁移),测试环境也需要搭建相应的codis服务,
鉴于codis的一些特性,大家在测试过程中有些地方需要注意:
1、线上大部分应用都使用同一codis集群,所以各个应用模块的key命名需要规范,避免key冲突的情况。
2、只能使用db0 的库,其它库均不支持
3、部分命令不支持,不支持的命令列表如下:
Command TypeCommand Name
KeysKEYS
MIGRATE
MOVE
OBJECT
RANDOMKEY
RENAME
RENAMENX
SCAN
StringsBITOP
MSETNX
ListsBLPOP
BRPOP
BRPOPLPUSH
Pub/SubPSUBSCRIBE
PUBLISH
PUNSUBSCRIBE
SUBSCRIBE
UNSUBSCRIBE
TransactionsDISCARD
EXEC
MULTI
UNWATCH
WATCH
ScriptingSCRIPT
ServerBGREWRITEAOF
BGSAVE
CLIENT
CONFIG
DBSIZE
DEBUG
FLUSHALL
FLUSHDB
LASTSAVE
MONITOR
RESTORE
SAVE
SHUTDOWN
SLAVEOF
SLOWLOG
SYNC
TIME
Codis SlotSLOTSCHECK
SLOTSDEL
SLOTSINFO
SLOTSMGRTONE
SLOTSMGRTSLOT
SLOTSMGRTTAGONE
SLOTSMGRTTAGSLOT
 
codis最简版搭建已经放到知识库了:《最简版codis(redis)搭建》
运维也会在预发布搭建简易的codis集群环境。
 
一、zookeeper安装:
1、下载解压
2、将conf下的zoo_sample.cfg改为zoo.cfg,配置:
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/opt/zookeeper/data
dataLogDir=/opt/zookeeper/log
clientPort=2181
server.1=192.168.7.21:2888:3888
 
注意,建data和log目录
3、data下新建myid文件,每个zookeeper写入不同的id
4、./bin/zkSever.sh start启动
 
二、部署codis
四、服务启动,集群初始化
1、启动dashboard(codis-config上操作)
# cat config.ini
zk=192.168.7.21:2181
product=codis-cluster
proxy_id=proxy_1
net_timeout=30
dashboard_addr=0.0.0.0:18087
coordinator=zookeeper
 
nohup ../bin/codis-config -c config.ini -L ./log/dashboard.log dashboard --addr=:18087 --http-log=./log/requests.log &
 
 
2、初始化slots(codis-config上操作)
../bin/codis-config -c ./config.ini slot init
 
 
3、启动codis(等同于redis,基于redis2.8.13开发,加入了slot支持和原子的数据迁移指令,且codis-proxy和codis-config只能和这个版本进行交互)(在codis-server上操作)
../bin/codis-server ./redis_conf/6379.conf
 
4、添加redis server group(可以在dashboard上操作),每个group最多有一个master,可以有多个slave(在codis-config上操作)
命令模版:codis-config server add <group_id> <redis_addr> <role>
添加两个 server group, 每个 group 有两个 redis 实例,group的id分别为1和2, redis实例为一主一从。
../bin/codis-config -c ./config.ini server add 1 192.168.7.215:6379 master
 
 
5、设置每个slot由那个sever group来提供服务(可以在dashboard上操作),默认slots分成1024份(0-1023)(codis-config上操作)
../bin/codis-config -c ./config.ini slot range-set 0 1023 online
 
6、启动codis-proxy
# cat config.ini
zk=192.168.7.21:2181
product=codis-cluster
proxy_id=proxy_103
net_timeout=30
dashboard_addr=0.0.0.0:18087
coordinator=zookeeper
注意:proxy_id在同一个集群里是唯一的
 
nohup ../bin/codis-proxy -c ./config.ini -L /var/log/codis/codis-proxy.log --log-level=warn --cpu=8 --addr=0.0.0.0:1900 --http-addr=0.0.0.0:11000 &
 
proxy启动后需要online才可对外提供服务,可以在dashboard上进行online,或者用命令进行online
../bin/codis-config -c config.ini proxy online proxy_113
 
搭建好后,环境里的redis.properties的配置改成 codis-proxy的ip:codis-proxy的端口(1900)
example:
改之前:
redis.ip=192.168.7.217
redis.port=6379
改成新的codis:
redis.ip=192.168.7.103 
redis.port=1900
 
可以通过http://ip:18087/admin 访问codis管理页面。

猜你喜欢

转载自curious.iteye.com/blog/2275486