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上。