搭建Redis服务
下载Redis
Redis的官网:http://redis.io/
下载地址:http://download.redis.io/releases/
我这里以redis-3.0.0版本来进行搭建
第一步在Linux环境中执行命令下载该版本:
wget http://download.redis.io/releases/redis-3.0.0.tar.gz
下载截图:
第二步解压下载下来的压缩文件
解压命令:
tar -zxvf redis-3.0.0.tar.gz
解压后的截图:
安装Redis
由于Redis是C语言开发的,因此需要让操作系统具有C环境(注意:CentOS自带gcc环境)
第一步在Linux环境中安装gcc环境(用于编译C语言开发的应用)
yum install -y gcc-c++
由于刚才解压的文件在用户的家目录下,此时需要把解压后的redis文件移动到/usr/local/redis目录下:
mv redis-3.0.0 /usr/local/redis/
第二步编译redis源码
cd /usr/local/redis/redis-3.0.0
make
第三步安装redis(我这里安装目录安装到/usr/local/redis)
make install PREFIX=/usr/local/redis/redis-master
安装完后在/usr/local/redis/目录中就多出来了一个目录:redis01
启动Redis
前台启动Redis
启动方式先进入安装生产的目录中的bin目录
cd /usr/local/redis/redis01/bin
查看该目录有哪些文件:
ls
执行一项命令进行启动服务:
./redis-server
启动的结果图:
前台关闭Redis服务
直接使用快捷键Ctril+C
后台启动Redis服务
第一步将Redis源码包中的redis.conf配置文件复制到安装目录的bin目录中(/usr/local/redis/redis01/bin/)
cp /usr/local/redis/redis-3.0.0/redis.conf /usr/local/redis/redis01/bin/
第二步修改redis.conf配置文件,把daemonize由no改为yes
vim /usr/local/redis/redis01/bin/redis.conf
第三步执行命令后台启动Redis服务
/usr/local/redis/redis01/bin/redis-server redis.conf
第四步查看是否启动成功
ps -aux|grep redis
关闭后台启动的Redis服务
方式一强制关闭也叫非正式关闭(不推荐使用)
kill -9 6695
方式二正式关闭
usr/local/redis/redis01/bin/redis-cli shutdown
Redis自带客户端
打开Redis自带的客户端
/usr/local/redis/redis01/bin/redis-cli -h 127.0.0.1 -p 6379
-h:redis服务器IP地址。默认地址是:127.0.0.1
-p:redis实例端口号。默认端口为:6379
Redis服务本类就对外服务的,因此我们需要设置Redis服务端口防火墙开放
echo '-A INPUT -m state --state NEW -m tcp -p tcp --dport 6379 -j ACCEPT' >>/etc/sysconfig/iptables
再重启防火墙:
service iptables restart
到这里就已经在Linux系统中搭建起了Redis的服务了
Linux修改Redis持久化方案
rdb持久化
rdb方式的持久化是通过快照(snapshotting)完成的,当符合一定条件时Redis会自动将内存中的数据进行快照并持久化到硬盘。rdb是Redis默认采用的持久化方式。
“save 900 1”表示15分钟(900秒钟)内至少1个键被更改则进行快照。
“save 300 10”表示5分钟(300秒)内至少10个键被更改则进行快照。
配置快照文件目录
在redis.conf文件中配置dir
配置快照文件名称
Redis启动后会读取RDB快照文件,将数据从硬盘载入到内存。根据数据量大小与结构和服务器性能不同,这个时间也不同。通常将记录一千万个字符串类型键、大小为1GB的快照文件载入到内存中需要花费20~30秒钟。
rdb的不足点
通过RDB方式实现持久化,一旦Redis异常退出,就会丢失最后一次快照以后更改的所有数据。这就需要开发者根据具体的应用场合,通过组合设置自动快照条件的方式来将可能发生的数据损失控制在能够接受的范围。
如果数据很重要以至于无法承受任何损失,则可以考虑使用AOF方式进行持久化。
aof持久化
默认情况下Redis没有开启aof(append only file)方式的持久化。
开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬
盘中的AOF文件。
开启aof
aof持久化文件名称修改
aof持久化文件的路径和rdb路径一样
Linux环境中配置Redis的主从复制
什么是主从复制
持久化保证了即使redis服务重启也不会丢失数据,因为redis服务重启后会将硬盘上持久化的数据恢复到内存中,但是当redis服务器的硬盘损坏了可能会导致数据丢失,如果通过redis的主从复制机制就可以避免这种单点故障。
说明
- 1主redis中的数据有两个副本(replication)即从redis1和从redis2,即使一台redis服务器崩溃了,其它两台redis服务也可以继续提供服务。
- 2主redis中的数据和从redis上的数据保持实时同步,当主redis写入数据时通过主从复制机制会复制到两个从redis服务上。
- 3一个主redis,可以有多个从redis。
- 4主从复制不会阻塞master,在同步数据时,master 可以继续处理client 请求。
- 5一个redis可以即是主又是从。
- 6从机不能执行写的操作。
主Redis配置
主Redis其实不需要进行任何配置
从Redis配置
修改从redis服务器上的redis.conf文件
关于怎么配置主机崩溃了,从机顶上,主机好了,从机再次退下的配置,可以在网上了解下
Linux环境中搭建Redis集群
架构细节
(1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
(2)节点的fail是通过集群中超过半数的节点检测失效时才生效.
(3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
(4)redis-cluster把所有的物理节点映射到[0-16383]slot(槽)上,cluster 负责维护node<->slot<->value
(5)Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点
Redis集群容错
(1)集群中所有master参与投票,如果半数以上master节点与其中一个master节点通信超过(cluster-node-timeout),认为该master节点挂掉.
(2):什么时候整个集群不可用(cluster_state:fail)?
如果集群任意master挂掉,且当前master(主机)没有slave(从机),则集群进入fail状态。也可以理解成集群的[0-16383]slot映射不完全时进入fail状态。
如果集群超过半数以上master(主机)挂掉,无论是否有slave(从机),集群进入fail状态。
准备搭建Redis集群环境
在这里我们就通过一台电脑,在上面搭建6个Redis服务来作为集群的演示(3台主机,3台从机)
搭建Ruby环境
redis集群管理工具redis-trib.rb(该管理工具是用ruby脚本写的)依赖ruby环境,首先需要安装ruby环境。
yum install -y ruby
yum install -y rubygems
通过gem安装ruby和redis接口:(如果没有接口,可以自己去下载redis对应版本的接口)
gem install redis-3.0.0.gem
搭建集群
创建集群存放Linux所在的目录:
mkdir -p /usr/local/redis/redis-cluster/
把之前安装的redis文件的bin目录拷贝到上面创建的目录中,并改名为redis-cluster-7001:
cp -r bin /usr/local/redis-cluster/reids-cluster-7001
将拷贝的redis目录中的持久化文件删除和修改redis.conf配置文件中的端口和打开redis集群:
rm -r appendonly.aof dump.rdb
修改redis.conf中的端口为7001,和打开集群:cluster-enabled yes
复制redis-cluster-7001五份,并重命名为redis-cluster-7002到redis-cluster-7006,并修改里面的redis.conf文件中端口也从7002到7006:
cp -r redis-cluster-7001 redis-cluster-7002
cp -r redis-cluster-7001 redis-cluster-7003
cp -r redis-cluster-7001 redis-cluster-7004
cp -r redis-cluster-7001 redis-cluster-7005
cp -r redis-cluster-7001 redis-cluster-7006
修改端口就不展示了;
启动这六台redis服务(下面是启动的shell脚本)
cd redis-cluster-7001
./redis-server redis.conf
cd ..
cd redis-cluster-7002
./redis-server redis.conf
cd ..
cd redis-cluster-7003
./redis-server redis.conf
cd ..
cd redis-cluster-7004
./redis-server redis.conf
cd ..
cd redis-cluster-7005
./redis-server redis.conf
cd ..
cd redis-cluster-7006
./redis-server redis.conf
cd ..
把redis-trib.rb(redis解压包中src目录下)拷贝到集群所在的目录:
cp redis-trib.rb /usr/local/redis/redis-cluster/
创建集群:在集群所在的目录执行以下命令;
./redis-trib.rb create --replicas 1 192.168.211.128:7001 192.168.211.128:7002 192.168.211.128:7003 192.168.211.128:7004 192.168.211.128:7005 192.168.211.128:7006
连接集群
cd /usr/local/redis/redis-cluster/redis-cluster-7001/
./redis-cli -h 192.168.211.128 -p 7001 -c
连接上后通过命令查看集群信息:
cluster info
查看结果:
测试
向集群中添加三个数据,看是不是平均分布到各个节点上进行存储:
节点的维护
添加主节点
在集群中添加一个节点(并删除节点中的所有缓存信息):
cp -r redis-cluster-7001 redis-cluster-7007
cd redis-cluster-7007
rm dump.rdb appendonly.aof -
修改新增的节点端口为7007端口;
添加7007节点作为新节点(只需要新增的节点和集群中任意一个节点连接就可以进行添加了):
./redis-trib.rb add-node 192.168.211.128:7007 192.168.211.128:7001
hash槽重新分配
添加完主节点需要对主节点进行hash槽分配,这样该主节才可以存储数据(连接集群中任意一个可用的节点都可以)。
./redis-trib.rb reshard 192.168.101.3:7001
输入要分配的槽数量:
输入:1000,表示分配1000个槽点;
输入接收槽的结点id:
也就是新增节点的id;
输入源结点id:
输入yes开始移动槽到目标结点id:
添加从节点
在上面添加了一个主节点7007,现在给主节点7007添加一个从节点:
./redis-trib.rb add-node --slave --master-id cad9f7413ec6842c971dbcc2c48b4ca959eb5db4 192.168.211.128:7008 192.168.211.128:7001
cad9f7413ec6842c971dbcc2c48b4ca959eb5db4这个是需要添加从节点的id(也就是7007节点的id);
注意:如果原来该结点在集群中的配置信息已经生成到cluster-config-file指定的配置文件中(如果cluster-config-file没有指定则默认为nodes.conf),这时可能会报错:
[ERR] Node XXXXXX is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0
解决方法:解决方法是删除生成的配置文件nodes.conf,删除后再执行上面添加从节点的方法;
删除节点
./redis-trib.rb del-node 192.168.211.128:7005 4b45eb75c8b428fbd77ab979b85080146a9bc017
4b45eb75c8b428fbd77ab979b85080146a9bc017这个是要删除节点的id
注意:如果删除的节点占有槽,删除会报错的。
解决方法:在删除节点前给该节点从新分配槽(分配0个槽),然后再删除该节点;