redis是一个开源的,使用C语言编写的,支持网络交互的,可基于内存也可持久化的Key-Value数据库。
一、安装redis
下载redis源码
> wget http://download.redis.io/releases/redis-3.2.6.tar.gz
解压安装
> tar xf redis-3.2.6.tar.gz
> cd redis-3.2.6
> make PREFIX=/data/redis install
把redis自带的启动脚本复制到/etc/init.d下
> cp /data/redis-3.2.6/utils/redis_init_script /etc/init.d/redis
由于我们redis的安装目录并不是默认的/usr/local/redis下,所以要修改启动脚本
> vi /etc/init.d/redis
#端口
REDISPORT=6379
#服务端命令路径
EXEC=/data/redis/bin/redis-server
#命令行命令路径
CLIEXEC=/data/redis/bin/redis-cli
#pid文件路径
PIDFILE=/data/redis/redis_${REDISPORT}.pid
#配置文件路径
CONF="/data/redis/${REDISPORT}.conf"
给该脚本可运行的权限
> chmod 755 /etc/init.d/redis
复制配置文件到我们刚配置的路径下
> cp /data/redis-3.2.6/redis.conf /data/redis/6379.conf
并修改6379.conf中pidfile的路径与启动脚本一致
pidfile /data/redis/redis_6379.pid
启动redis
> service redis start
不过可以看到redis启动并不是在后台,这里需要修改一下。
> vi /data/redis/6379.conf
daemonize yes
> service redis start
> ps -ef|grep redis
给redis添加自启动
> chkconfig --add redis
如果出现服务 redis 不支持 chkconfig,请修改/etc/init.d/redis文件,在第二行添加运行级别
> vi /etc/init.d/redis
90表示启动优先级,10表示关闭优先级
chkconfig: 2345 90 10
> chkconfig redis on
> chkconfig --list redis
给redis命令加入环境变量中
> echo 'export PATH=/data/redis/bin:$PATH' >> /etc/profile
> source /etc/profile
二、redis基本命令的使用
登陆redis
> redis-cli -h 127.0.0.1 -p 6379
set操作
> set k1 123456
get操作
> get k1
查找所有key
> keys *
判断key是否存在
> exists 123
删除指定key
> del k1
获取key的类型
> type k1
查看当前redis的信息
> info
选择不同的db,redis中的db并没有很强的区分
> select 1
清除所有的key
> flushall
三、redis基本配置
> vi /etc/redis/6379.conf
#pid文件,需与启动脚本一致
pidfile /data/redis/redis_6379.pid
#日志文件
logfile = "/data/redis/logs/redis.log"
#数据库最多16个,可修改
databases 16
#持久化文件保存路径rdb和aof
dir ./
四、redis的五种数据类型
1、字符串类型
SET 设置
> set 111 hello
GET 获取
> get 111
DEL 删除
> del 111
APPEND 追加
> append world
STRLEN 获取字符串长度
> strlen 111
MGET 获取多个
> mget key1 key2 key3
MSET 设置多个
> mset key1 v1 key2 v2 key3 v3
INCR 自增+1
> incr num
INCRBY 自增+n
> incrby num 10
DECR 自减-1
> decr num
DECRBY 自减-n
> decrby num 5
INCRBYFLOAT 自增+浮点
> incrbyfloat num 0.1
2、散列类型
hset key field value 设置散列
> hset phone name iphone
> hset phone color red
> hset phone price 6888
hget key field 获取散列
> hget phone color
hmset key field value [field value] 设置多个散列值
> hmset pc name thinkpad color black price 5999
hmget key field[field] 获取多个散列值
> hmget pc name color price
hgetall key 获取所有散列
> hgetall phone
hdel key field 删除散列字段
> hdel phone name
hexists key field 判断散列字段是否存在
> hexists phone name
3、列表类型
lpush key value [value ...] 从左边加入
> lpush test 1
> lpush test 2
rpush key value [value ...] 从右边加入
> rpush test 3
> rpush test 4
llen key 获取列表长度
> llen test
lpop key 从左边弹出
> lpop test
rpop key 从右边弹出
> rpop test
lrange key start stop 返回指定范围内的元素
> lrange test 1 5
lrem key count value 移除前count次出现值为value的元素
> lrem test 1 "hello"
> lrem test -1 "hello"
lindex key index 获取指定位置的元素
> lindex test 1
> lindex test -1
ltrim key start stop 保留指定范围内的元素
> ltrim test 0 3
4、集合类型
sadd key member [member ...] 设置集合
> sadd test a b c
> sadd test2 c b d
srem key member [member ..] 删除集合成员
> srem test b c
smembers key 获取集合所有内容
> smembers test
sismember key member 判断成员是否存在集合内
> sismember test a
sdiff key [key ...] 集合的差集
> adiff test test2
sinter key [key ...] 集合的交集
> sinter test test2
sunion key [key ...] 集合的并集
> sunion test test2
5、有序集合
zadd key score member 增加元素
> zadd test 10 a
> zadd test 20 b
> zadd test 5 c
zrem key member [member ...] 删除元素
> zrem test b
zscore key member 获取元素分数
> zscore test a
zrange key start stop [withscores] 返回指定范围内的元素,按分数从小到大排序
> zrange test 0 2
zrangebyscore key min max 返回分数在min和max之间的元素,
> zrangebyscore test 5 10
五、redis的发布与订阅
subscribe channel [channel ...] 订阅一个或多个频道
> subscribe hehe
publish channel message 将消息发给指定频道
> publist hehe "hello,world"
unsubscribe [channel ...] 退出指定频道
> unsubscribe hehe
六、redis的持久化
持久化支持两种方式:
RDB 在指定时间间隔内把内存数据快照一下保存下来。(默认)
AOF 把所有的执行命令记录下来保存到文件,启动时再执行一遍。
1、RDB方式
> vi /data/redis/6379.conf
#在900秒内有一次改变
save 900 1
#在300秒内有十次改变
save 300 10
#在60秒内有一万次改变
save 60 10000
#rdb文件名
dbfilename dump_6379.rdb
#rdb和aof文件保存路径
dir /data/redis
重启redis
> service redis restart
进入命令行模式
> redis-cli
手动保存,save阻塞方式,bgsave非阻塞
> save
> bgsave
2、AOF方式
> vi /data/redis/6379.conf
#是否开启aof
appendonly yes
#aof文件名
appendfilename "appendonly.aof"
七、redis的主从复制
为了更好的实验,我们在虚拟机上再开个redis服务。
我们创建一个目录,用来放置redis文件
> mkdir -p /data/redis/6380
复制配置文件
> cp /data/redis/6379.conf /data/redis/6380/6380.conf
修改配置文件
port 6380
pidfile /data/redis/6380/redis_6380.pid
dbfilename dump_6380.rdb
dir /data/redis/6380
logfile = "/data/redis/6380/redis.log"
然后复制启动脚本
> cp /etc/init.d/redis /etc/init.d/redis2
修改启动脚本
> vi /etc/init.d/redis2
REDISPORT=6380
PIDFILE=/data/redis/6380/redis_${REDISPORT}.pid
CONF="/data/redis/6380/${REDISPORT}.conf"
启动这个服务
> service redis2 start
查看这个服务启动成功没有
> ps aux|grep redis
我们通过cli命令登陆到6380服务上,我们把6380作为从服务,默认的6379作为主服务
> redis-cli -h 127.0.0.1 -p 6380
> slaveof 127.0.0.1 6379
登出主服务上,查看
> redis-cli
> info
可以看有一个从服务已经连上了,一旦设置了从服务,那从服务就是只读了,无法写入数据。
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=15,lag=1
master_repl_offset:15
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:14
八、redis的cluster集群配置
我们创建5个redis服务,配置同上面添加6380服务一样。
把以下配置复制到每个redis配置文件中
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
分别启动redis服务,查看服务是否启动成功
> ps -aux|grep redis
root 2634 0.0 0.7 33328 7544 ? Ssl 18:34 0:00 /data/redis/bin/redis-server 127.0.0.1:6381 [cluster]
root 2653 0.0 0.7 33328 7552 ? Ssl 18:34 0:00 /data/redis/bin/redis-server 127.0.0.1:6382 [cluster]
root 2670 0.1 0.2 33328 2568 ? Ssl 18:35 0:00 /data/redis/bin/redis-server 127.0.0.1:6383 [cluster]
root 2700 0.1 0.7 35376 7704 ? Ssl 18:35 0:00 /data/redis/bin/redis-server 127.0.0.1:6379 [cluster]
root 2730 0.0 0.7 33328 7612 ? Ssl 18:35 0:00 /data/redis/bin/redis-server 127.0.0.1:6380 [cluster]
root 2897 0.0 0.2 33328 2572 ? Ssl 19:21 0:00 /data/redis/bin/redis-server 127.0.0.1:6384 [cluster]
root 2914 0.0 0.2 33328 2568 ? Ssl 19:21 0:00 /data/redis/bin/redis-server 127.0.0.1:6385 [cluster]
redis自带的集群工具是用ruby写的,需要安装ruby
> yum install ruby rubygems
> gem install redis
如果安装过程中出现错误或超时,请运行下面然后重新安装
> gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/
> gem sources -l
复制redis-trib.rb文件到redis的bin目录下
> cp /data/redis-3.2.6/src/redis-trib.rb /data/redis/bin/redis-trib
查看帮助信息
> redis-trib help
创建集群,集群最少3台master,3台slave,共6台
--replicas 1表示集群每个主节点创建一个从节点
> redis-trib create --replicas 1 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385
如果出现如下信息:
Node 127.0.0.1:6380 is not empty. Either the node already knows other nodes
1、把6380下的aof,rdb文件删除
2、同时把配置中cluster-config-file的nodes.conf删除
3、清空6380中的所有数据
如果出现如下信息:
ERR Slot 4618 is already busy
请用redis-cli登陆到每个节点执行flushall和cluster reset
连上集群
> redis-cli -c -h 127.0.0.1 -p 6380
查看集群节点
> cluster nodes
查看集群状态
> cluster info
添加节点
> redis-trib add-node 127.0.0.1:6386 127.0.0.1:6380
分配槽位到哪些节点
> redis-trib reshard 127.0.0.1:6386
设置为某节点的从节点
> cluster replicate 节点ID
删除从节点
> redis-trib del-node 127.0.0.1:6386 节点ID
删除主节点
如果主节点有从节点,将从节点转移到其他主节点。
如果主节点有slot,转移slot,并删除。
九、redis的codis3集群配置
https://github.com/CodisLabs/codis
1、安装GO语言
> yum install golang
2、设置编译环境
> mkdir -p /data/gopath
> echo "export GOPATH=/data/gopath" >> /etc/profile
> source /etc/profile
安装godep工具
> go get -u github.com/tools/godep && which godep
如果现如下问题:
package github.com/tools/godep: exec: "git": executable file not found in $PATH
请安装git
> yum install git
3、下载codis源码
> mkdir -p $GOPATH/src/github.com/CodisLabs
过入上面创建的目录并下载源码
> cd $_ && git clone https://github.com/CodisLabs/codis.git -b release3.1
4、编译codis
> cd $GOPATH/src/github.com/CodisLabs/codis
> make
复制安装目录到/data/codis下
> cp -R ./ /data/codis
5、安装zookeeper
> yum install -y java
> cd /data
> wget http://apache.fayea.com/zookeeper/zookeeper-3.4.9/zookeeper-3.4.9.tar.gz
> tar xf zookeeper-3.4.9.tar.gz
> mv zookeeper-3.4.9 zookeeper
创建三个zookeeper目录,存放数据
> mkdir -p /data/zk1 /data/zk2 /data/zk3
第个zookeeper需要一个文件存放ID
> echo "1" >> /data/zk1/myid
> echo "2" >> /data/zk2/myid
> echo "3" >> /data/zk3/myid
zookeeper的配置文件
> cd /data/zookeeper
> cp ./conf/zoo_sample.cfg /data/zk1/zk1.cfg
> cp ./conf/zoo_sample.cfg /data/zk2/zk2.cfg
> cp ./conf/zoo_sample.cfg /data/zk3/zk3.cfg
修改配置文件
#心跳的时间间隔
tickTime=2000
#连接时最长能忍受多少个心跳时间间隔数
initLimit=10
#发送消息时请求和应答时间长度
syncLimit=5
#数据目录
dataDir=/data/zk1/
#日志目录
dataLogDir
#客户端连接端口
clientPort=2181
#1,2,3表示服务器ID
#第一个端口是信息交换端口,第二个端口是选举端口
server.1=127.0.0.1:7001:7010
server.2=127.0.0.1:7002:7020
server.3=127.0.0.1:7003:7030
分别启动这三个zookeeper
> /data/zookeeper/bin/zkServer.sh start /data/zk1/zk1.cfg
> /data/zookeeper/bin/zkServer.sh start /data/zk2/zk2.cfg
> /data/zookeeper/bin/zkServer.sh start /data/zk3/zk3.cfg
查看zk1,zk2,zk3的状态
> /data/zookeeper/bin/zkServer.sh status /data/zk1/zk1.cfg
> /data/zookeeper/bin/zkServer.sh status /data/zk2/zk2.cfg
> /data/zookeeper/bin/zkServer.sh status /data/zk3/zk3.cfg
连接上zookeeper服务上
> /data/zookeeper/bin/zkCli.sh -server 127.0.0.1:2182
6、codis dashboard的配置
集群管理工具,同一个时刻 codis-dashboard只能有0个或者1个。
> cd /data/codis
> vi ./config/dashboard.toml
#外部存储类型
coordinator_name = "zookeeper"
#外部存储地址
coordinator_addr = "127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183"
#集群名称
product_name = "test"
#集群密码,默认为空
product_auth = "test"
#RESTful API 端口
admin_addr = "127.0.0.1:11111"
启动dashboard
> mkdir log
> /data/codis/bin/codis-dashboard \
--config=/data/codis/config/dashboard.toml \
--host-admin=127.0.0.1:11111 \
--log=/data/codis/log/dashboard.log &
不要用kill命令来关闭dashboard,一旦异常退出,之前LOCK未安全删除,重启往往会失败。
> /data/codis/bin/codis-admin --remove-lock --product=test --zookeeper=127.0.0.1:2181
> /data/codis/bin/codis-admin --remove-lock --product=test --zookeeper=127.0.0.1:2182
> /data/codis/bin/codis-admin --remove-lock --product=test --zookeeper=127.0.0.1:2183
7、Codis Proxy的配置
客户端连接的redis代理服务,可以启动多个,这里我们启动两个。
> cp ./config/proxy.toml ./config/proxy1.toml
> cp ./config/proxy.toml ./config/proxy2.toml
> vi ./config/proxy1.toml
#这里填写的需与dashboard设置的一致
product_name = "test"
product_auth = "test"
admin_addr = "127.0.0.1:11112"
#这里根据需要修改
proto_type = "tcp4"
proxy_addr = "127.0.0.1:19000"
另一个同上,把admin_addr中端口改为11113,proxy_addr中端口改成19001
启动proxy
> /data/codis/bin/codis-proxy \
--config=/data/codis/config/proxy1.toml \
--host-admin=127.0.0.1:11112 \
--log=/data/codis/log/proxy1.log &
> /data/codis/bin/codis-proxy \
--config=/data/codis/config/proxy2.toml \
--host-admin=127.0.0.1:11113 \
--log=/data/codis/log/proxy2.log &
通过codis-admin来把proxy添加到集群
注意这里dashboard填写的是dashboard的admin_addr,create-proxy填写的是proxy的admin_addr
> /data/codis/bin/codis-admin --dashboard=127.0.0.1:11111 --create-proxy -x 127.0.0.1:11112
> /data/codis/bin/codis-admin --dashboard=127.0.0.1:11111 --create-proxy -x 127.0.0.1:11113
8、Codis Server的配置
基于 redis-2.8.21 分支开发。增加了额外的数据结构,与启动普通 redis 的方法一致。
我们这里启动四个codis server。
创建四个目录用于存放codis server
> mkdir -p /data/codis/redis/12000
> mkdir -p /data/codis/redis/12001
> mkdir -p /data/codis/redis/12002
> mkdir -p /data/codis/redis/12003
先复制配置文件
> cp /data/codis/extern/redis-2.8.21/redis.conf /data/codis/redis/12000/12000.conf
> cp /data/codis/extern/redis-2.8.21/redis.conf /data/codis/redis/12001/12001.conf
> cp /data/codis/extern/redis-2.8.21/redis.conf /data/codis/redis/12002/12002.conf
> cp /data/codis/extern/redis-2.8.21/redis.conf /data/codis/redis/12003/12003.conf
修改配置文件
#注意这里设置的要跟dashboard里的product_auth一样
maxmemory 10m
requirepass test
port 12000
pidfile /data/codis/redis/12000/redis_12000.pid
dbfilename dump_12000.rdb
dir /data/codis/redis/12000
logfile = "/data/codis/redis/12000/redis.log"
其他三个同上,修改相应位置。
启动四个codis server
> /data/codis/bin/codis-server /data/codis/redis/12000/12000.conf
> /data/codis/bin/codis-server /data/codis/redis/12001/12001.conf
> /data/codis/bin/codis-server /data/codis/redis/12002/12002.conf
> /data/codis/bin/codis-server /data/codis/redis/12003/12003.conf
通过codis-admin添加组并把server加入组
> /data/codis/bin/codis-admin --dashboard=127.0.0.1:11111 --create-group --gid=1
> /data/codis/bin/codis-admin --dashboard=127.0.0.1:11111 --create-group --gid=2
> /data/codis/bin/codis-admin --dashboard=127.0.0.1:11111 --group-add --gid=1 --addr=127.0.0.1:12000
> /data/codis/bin/codis-admin --dashboard=127.0.0.1:11111 --group-add --gid=1 --addr=127.0.0.1:12001
> /data/codis/bin/codis-admin --dashboard=127.0.0.1:11111 --group-add --gid=2 --addr=127.0.0.1:12002
> /data/codis/bin/codis-admin --dashboard=127.0.0.1:11111 --group-add --gid=2 --addr=127.0.0.1:12003
然后通过codis-admin分配槽位给组,注意这里好像一定要分满1024个槽位,没有分满,登陆proxy上,死活set不了数据
> /data/codis/bin/codis-admin --dashboard=127.0.0.1:11111 --slot-action --create-range --beg=0 --end=255 --gid=1
> /data/codis/bin/codis-admin --dashboard=127.0.0.1:11111 --slot-action --create-range --beg=256 --end=511 --gid=2
> /data/codis/bin/codis-admin --dashboard=127.0.0.1:11111 --slot-action --create-range --beg=512 --end=767 --gid=1
> /data/codis/bin/codis-admin --dashboard=127.0.0.1:11111 --slot-action --create-range --beg=768 --end=1023 --gid=2
9、Codis FE的配置
一个前端集群管理界面
生成codis.json文件供fe使用
> cd /data/codis/config
> /data/codis/bin/codis-admin --dashboard-list --zookeeper=127.0.0.1:2181 | tee codis.json
启动fe
> /data/codis/bin/codis-fe \
--dashboard-list=/data/codis/config/codis.json \
--log=/data/codis/log/fe.log \
--listen=127.0.0.1:33333 &
启动成功后,就可以在浏览器中通过127.0.0.1:33333来访问了。
10、Codis HA的配置
为集群提供高可用,依赖 codis-dashboard 实例,自动抓取集群各个组件的状态。
启动codis ha
> /data/codis/bin/codis-ha \
--log=/data/codis/log/ha.log \
--log-level=WARN \
--dashboard=127.0.0.1:11111 &
11、测试
整个配置就算完成了,这里整理一下。
codis的目录在 /data/codis
codis的日志统一在 /data/codis/log 下
dashboard和proxy的配置在 /data/codis/config 下
codis server的目录在 /data/codis/redis/端口
创建了三个zookeeper,客户端连接端口分别是2181,2182,2183
一个codis dashboard的服务,admin_addr端口号11111
二个codis proxy,admin_addr端口号为11112,11113,proxy_addr端口为19000,19001
四个codis server,端口为12000,12001,12002,12003
一个codis fe服务,端口号为33333
一个codis ha服务
我们像登陆redis一样,登陆proxy的接口
> /data/codis/bin/redis-cli -h 127.0.0.1 -p 19000 -a test
> info
添加一些测试数据
> set a 1
> set b 2
> set c 3
我们分别登陆到codis server上查看,数据放在了哪个server上。