codis简介:
codis是一个分布式redis集群解决方案,对于上层的应用来说, 连接到codis-proxy和连接原生的redis-server没有明显的区别。
上层应用可以像使用单机的redis一样使用,codis底层会处理请求的转发,不停机的数据迁移等工作。所有后边的一切事情,
对于前面的客户端来说是透明的,可以简单的认为后边连接的是一个内存无限大的redis服务。
codis由四部分组成:
codis proxy(codis-proxy)
codis dashboard(codis-config)
codis redis(codis-server)
zookeeper/etcd
codis-proxy是客户端连接的redis代理服务,codis-proxy本身实现了redis协议,表现得和一个原生的redis没什么区别
codis-config是codis的管理工具,支持包括:添加/删除redis节点,添加/删除proxy节点,发起数据迁移等操作。
codis-config本身还自带了一个http-server,会启动一个dashboard,用户可以直接在浏览器上观察codis集群的运行状态。
codis-server是codis项目维护的一个redis分支,基于redis2.8.21开发,加入了slot的支持和原子的数据迁移指令。codis上层
的codis-proxy和codis-config只能和这个版本的redis交互才能正常运行。
codis依赖zookeeper来存放数据路由表和codis-proxy节点的元信息,codis-config发起的命令都会通过zookeeper同步到各个
存活的codis-proxy。
codis的优缺点:
Codis是一套用go语言编写的,为了应对高并环境下的redis集群软件,原理是对一个redis key操作前,
先把这个key通过crc32算法,分配到不同redis的某一个slot上,实现并发读写功能.而且能通过zookeeper
调用redis-sentinel来实现故障切换功能.现在最新版本是3.2.1,依托于redis3.2.9开发出来.
优点:实现高并发读写,数据一致性高.
缺点:性能有较大损耗,故障切换无法保证不丢key,无法进行读写分离.
简单搭建一个web集群,实验环境:
server2:172.25.254.2
.bash_profile和.bashrc的区别:
/etc/profile: 此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行.
并从/etc/profile.d目录的配置文件中搜集shell的设置.
/etc/bashrc: 为每一个运行bash shell的用户执行此文件.当bash shell被打开时,该文件被读取.
~/.bash_profile: 每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,
该文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件.
~/.bashrc: 该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,
该该文件被读取.
~/.bash_logout: 当每次退出系统(退出bash shell)时,执行该文件.
另外,/etc/profile中设定的变量(全局)的可以作用于任何用户,而~/.bashrc等中设定的变量(局部)
只能继承/etc/profile中的变量,他们是"父子"关系.
配置环境变量:
[root@server2 ~]# ls
codis-release3.2.zip go1.8.linux-amd64.tar.gz
[root@server2 ~]# tar zxf go1.8.linux-amd64.tar.gz -C /usr/local/
[root@server2 ~]# pwd
/root
[root@server2 ~]# ls
codis-release3.2.zip go1.8.linux-amd64.tar.gz
[root@server2 ~]# vim .bash_profile
[root@server2 ~]# source .bash_profile 必须刷新生效
[root@server2 ~]# cat .bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin:/usr/local/go/bin
export PATH
[root@server2 ~]# go env go env用于打印Go语言的环境信息
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/root/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
Codis 源代码需要下载到 $GOPATH/src/github.com/CodisLabs/codis:
[root@server2 ~]# vim .bash_profile
[root@server2 ~]# source .bash_profile
[root@server2 ~]# cat .bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin:/usr/local/go/bin:/root/go/bin
export PATH
[root@server2 ~]# mkdir -p go/src/github.com/CodisLabs
配置codis进行编译:
[root@server2 ~]#unzip codis-release3.2.zip -d go/src/github.com/CodisLabs/
[root@server2 ~]# cd go/src/github.com/CodisLabs/codis-release3.2/
[root@server2 codis-release3.2]# ls
admin deploy extern pkg version
ansible doc Godeps README.md wandoujia_license.txt
cmd Dockerfile Makefile scripts
config example MIT-LICENSE.txt vendor
[root@server2 codis-release3.2]# cd ..
[root@server2 CodisLabs]# ls
codis-release3.2
[root@server2 CodisLabs]# mv codis-release3.2/ codis
[root@server2 CodisLabs]# cd codis/
[root@server2 codis]# ls
admin deploy extern pkg version
ansible doc Godeps README.md wandoujia_license.txt
cmd Dockerfile Makefile scripts
config example MIT-LICENSE.txt vendor
[root@server2 codis]# pwd
/root/go/src/github.com/CodisLabs/codis
[root@server2 codis]# ls
admin deploy extern pkg version
ansible doc Godeps README.md wandoujia_license.txt
cmd Dockerfile Makefile scripts
config example MIT-LICENSE.txt vendor
[root@server2 codis]# yum install -y git autoconf gcc 安装依赖性
直接使用make编译即可:
[root@server2 codis]# make 编译
[root@server2 codis]# ls
admin config example MIT-LICENSE.txt vendor
ansible deploy extern pkg version
bin doc Godeps README.md wandoujia_license.txt
cmd Dockerfile Makefile scripts
启动codis-dashboard
使用 codis-dashboard-admin.sh 脚本启动 dashboard,并查看 dashboard 日志确认启动是否有异常。
[root@server2 codis]# ./admin/codis-dashboard-admin.sh start
/root/go/src/github.com/CodisLabs/codis/admin/../config/dashboard.toml
starting codis-dashboard ...
启动codis-proxy
使用 codis-proxy-admin.sh 脚本启动 codis-proxy,并查看 proxy 日志确认启动是否有异常
[root@server2 codis]# ./admin/codis-proxy-admin.sh start
/root/go/src/github.com/CodisLabs/codis/admin/../config/proxy.toml
starting codis-proxy ...
启动codis-server
使用 codis-server-admin.sh 脚本启动 codis-server,并查看 redis 日志确认启动是否有异常。
[root@server2 codis]# ./admin/codis-server-admin.sh start
/root/go/src/github.com/CodisLabs/codis/admin/../config/redis.conf
starting codis-server ...
启动codis-fe
使用 codis-fe-admin.sh 脚本启动 codis-fe,并查看 fe 日志确认启动是否有异常。
[root@server2 codis]# ./admin/codis-fe-admin.sh start
starting codis-fe ...
通过web浏览器访问集群管理页面(fe地址:172.25.254.2:9090)
可以看到端口已经开启:
[root@server2 codis]# netstat -antlp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 8730/codis-server 1
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 909/sshd
tcp 0 0 0.0.0.0:19000 0.0.0.0:* LISTEN 8715/codis-proxy
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1487/master
tcp 0 0 172.25.254.2:54506 172.25.254.2:11080 TIME_WAIT -
tcp 0 0 172.25.254.2:22 172.25.254.84:59362 ESTABLISHED 1535/sshd
tcp 0 0 172.25.254.2:54507 172.25.254.2:11080 ESTABLISHED 8705/codis-dashboar
tcp 0 0 :::22 :::* LISTEN 909/sshd
tcp 0 0 ::1:25 :::* LISTEN 1487/master
tcp 0 0 :::18080 :::* LISTEN 8705/codis-dashboar
tcp 0 0 :::9090 :::* LISTEN 8737/codis-fe
tcp 0 0 :::11080 :::* LISTEN 8715/codis-proxy
tcp 0 0 :::3306 :::* LISTEN 1358/mysqld
tcp 0 0 ::ffff:172.25.254.2:11080 ::ffff:172.25.254.2:54507 ESTABLISHED 8715/codis-proxy
通过fe添加group:
通过web浏览器访问集群管理页面(fe地址:127.0.0.1:9090) 选择我们刚
搭建的集群 codis-demo,在 Proxy 栏可看到我们已经启动的 Proxy,
但是 Group 栏为空,因为我们启动的 codis-server 并未加入到集群
添加 NEW GROUP,NEW GROUP 行输入 1,再点击 NEW GROUP 即可
添加 Codis Server,Add Server 行输入我们刚刚启动的 codis-server
通过fe初始化slot:
新增的集群 slot 状态是 offline,因此我们需要对它进行初始化(将 1024 个 slot 分配到各个 group),
而初始化最快的方法可通过 fe 提供的 rebalance all slots 按钮来做,如下图所示,点击此按钮,我们
即快速完成了一个集群的搭建。
启动 ./bin/codis-server,与启动普通 redis 的方法一致。启动完成后,可以通过 codis-fe 提供的界面或者 codis-admin 命令行工具添加到集群中。
[root@server2 codis]# ls
admin config example Makefile scripts
ansible deploy extern MIT-LICENSE.txt vendor
bin doc Godeps pkg version
cmd Dockerfile log README.md wandoujia_license.txt
[root@server2 codis]# bin/codis-server
8743:C 12 Aug 20:46:20.694 # Warning: no config file specified, using the default config. In order to specify a config file use bin/codis-server /path/to/redis.conf
8743:M 12 Aug 20:46:20.694 * Increased maximum number of open files to 10032 (it was originally set to 1024).
8743:M 12 Aug 20:46:20.696 # Creating Server TCP listening socket *:6379: bind: Address already in use
[root@server2 codis]# ./bin/redis-cli
127.0.0.1:6379>
127.0.0.1:6379> info 查看6379的状态为master
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
# CPU
used_cpu_sys:0.93
used_cpu_user:0.59
used_cpu_sys_children:0.00
used_cpu_user_children:0.00
# Cluster
cluster_enabled:0
# Keyspace
/codis-proxy同样为master:
[root@server2 codis]# ./bin/redis-cli -p 19000
127.0.0.1:19000> info
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
# CPU
used_cpu_sys:1.00
used_cpu_user:0.64
used_cpu_sys_children:0.00
used_cpu_user_children:0.00
# Cluster
cluster_enabled:0
# Keyspace
127.0.0.1:19000> set name xfl
OK
127.0.0.1:19000> get name
"xfl"
127.0.0.1:19000> quit
创建集群:
[root@server2 ~]# cd go/src/github.com/CodisLabs/codis/
[root@server2 codis]# ls
admin doc log scripts
ansible Dockerfile Makefile vendor
bin dump.rdb MIT-LICENSE.txt version
cmd example pkg wandoujia_license.txt
config extern README.md
deploy Godeps redis1.conf
[root@server2 codis]# cd config/
[root@server2 config]# ls
dashboard.toml proxy.toml redis.conf sentinel.conf
[root@server2 config]# grep -v ^# redis.conf > redis1.conf
[root@server2 config]# vim redis1.conf
[root@server2 config]# cp redis1.conf redis2.conf
[root@server2 config]# cp redis1.conf redis3.conf
[root@server2 config]# vim redis2.conf
[root@server2 config]# vim redis3.conf
[root@server2 config]# cd ..
[root@server2 codis]# ./bin/codis-server config/redis1.conf 运行集群节点
[root@server2 codis]# ./bin/codis-server config/redis2.conf
[root@server2 codis]# ./bin/codis-server config/redis3.conf
[root@server2 codis]# ps ax
8789 ? Ssl 0:00 ./bin/codis-server 127.0.0.1:6381 可以查看集群节点状态
8794 ? Ssl 0:00 ./bin/codis-server 127.0.0.1:6382
8799 ? Ssl 0:00 ./bin/codis-server 127.0.0.1:6383
8803 pts/0 R+ 0:00 ps ax
通过fe添加group:
通过fe初始化slot:
有了键值:
[root@server2 codis]# cd bin/
[root@server2 bin]# ./redis-cli -p 19000
127.0.0.1:19000> get name
"xfl"
127.0.0.1:19000> set test test
OK
127.0.0.1:19000> get test
"test"
127.0.0.1:19000> set user1 xfl
OK
127.0.0.1:19000> set user2 xfl
OK
127.0.0.1:19000> set user3 xfl
OK
将6379杀死之后进行主备切换:
[root@server2 bin]# ps ax
8705 pts/0 Sl 0:14 /root/go/src/github.com/CodisLabs/codis/admi
8715 pts/0 Sl 0:05 /root/go/src/github.com/CodisLabs/codis/admi
8730 ? Ssl 0:03 /root/go/src/github.com/CodisLabs/codis/admi
8737 pts/0 Sl 0:00 /root/go/src/github.com/CodisLabs/codis/admi
8789 ? Ssl 0:00 ./bin/codis-server 127.0.0.1:6381
8794 ? Ssl 0:00 ./bin/codis-server 127.0.0.1:6382
8799 ? Ssl 0:00 ./bin/codis-server 127.0.0.1:6383
8806 ? S 0:00 pickup -l -t fifo -u
8825 pts/0 R+ 0:00 ps ax
[root@server2 bin]# kill -9 8730
在网页查看6379已经down掉:
[root@server2 bin]# ./redis-cli -p 19000
127.0.0.1:19000> get name
"xfl"
127.0.0.1:19000> get user1
(error) ERR handle response, backend conn reset
127.0.0.1:19000> get user2
(error) ERR handle response, backend conn reset
127.0.0.1:19000> get user3
(error) ERR handle response, backend conn reset
127.0.0.1:19000>
[root@server2 bin]# ./redis-cli -p 6381 验证备机可以正常获取数据
127.0.0.1:6381> get user1
"xfl"
127.0.0.1:6381> get user2
"xfl"
127.0.0.1:6381> get user3
"xfl"
127.0.0.1:6381>
[root@server2 bin]# ./redis-cli -p 19000
127.0.0.1:19000> get user1
(error) ERR handle response, backend conn reset
127.0.0.1:19000> get name
"xfl"
127.0.0.1:19000> get test
"test"
127.0.0.1:19000> set user4 xfl
(error) ERR handle response, backend conn reset
127.0.0.1:19000> set hello world
OK
127.0.0.1:19000> get hello
"world"
点击如图所示所有节点处于不同步状态: