Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。与Memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 是一个高性能的key-value数据库。Redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。[1]
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。
1.解压:tar -zxvf redis-3.0.5.tar.gz
2.make
3.make PREFIX=/root/training/redis install
4.cp ~/tools/redis-3.0.5/redis.conf /root/training/redis/etc/
参数
daemonize no 是否以后台运行的方式启动Redis,建议yes
port 6379 端口号
5.命令脚本
redis-benchmark 压力测试工具(测试AOF日志重写会用到)
redis-check-aof 检查AOF日志文件
redis-check-dump 检查RDB快照文件
redis-cli 客户端
redis-sentinel 哨兵,实现主从复制的HA(版本:2.4+)
redis-server 启动和停止Redis Server
6.启动 bin/redis-server conf/redis.conf
7.启动Redis的客户端:redis-cli
默认连接6739端口,也可以通过-p指定连接的端口号:bin/redis-cli -p 6379
./redis-cli --help显式帮助信息
Redis对事务的支持目前还比较简单。redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令。 由于redis是单线程来处理所有client的请求的所以做到这点是很容易的。一般情况下redis在接受到一个client发来的命令后会立即处理并 返回处理结果,但是当一个client在一个连接中发出multi命令有,这个连接会进入一个事务上下文,该连接后续的命令并不是立即执行,而是先放到一个队列中。当从此连接受到exec命令后,redis会顺序的执行队列中的所有命令。并将所有命令的运行结果打包到一起返回给client.然后此连接就 结束事务上下文。
Oracle数据库中的事务和Redis的事务对比
|
Oracle |
Redis |
开启事务的方式 |
自动开启事务 |
multi |
操作 |
DML语句 |
Redis命令 |
提交事务 |
commit |
exec |
回滚事务 |
rollback |
discard |
1.Redis的事务示例:银行转账
从Tom转100块钱给Mike
set tom 1000
set mike 1000
multi
decrby tom 100
incrby mike 100
exec
2.Redis的锁机制:watch
set ticket 1
set mike 1000
用户一: 用户二:在用户一提交前,已经将票买走
watch ticket
multi decr ticket
decr ticket
decr by mike 100
exec
@Test
public void testLock(){
Jedis jedis = new Jedis();
//对ticket加锁,如果在事务执行过程中,该值有变化,抛出异常
jedis.watch("ticket");
Transaction tc = null;
try{
//开启事务
tc = jedis.multi();
tc.decr("ticket");//车票减一
Thread.sleep(5000);
tc.decrBy("tom",100);
tc.exec();//提交事务
}catcht(Exceptin ex){
//回滚事务
tc.discard();
};
jedis.disconnect();
}
Redis 提供了多种不同级别的持久化方式:
配置参数:redis.conf文件
秒 key的个数
save 900 1 :15分钟内,如果有1key的value发生 变化,就执行RDB
save 300 10 :5分钟内,如果有10key的value发生 变化,就执行RDB
save 60 10000 : 60秒内,如果有10000key的value发生 变化,就执行RDB
如果执行RDB快照的时候,出现错误,停止客户端继续写入数据
stop-writes-on-bgsave-error yes
生成的RDB文件是否压缩
如果压缩,节约存储的空间,但是恢复效率低
如果不压缩,浪费存储的空间,但是恢复效率高
RDB的优点和缺点:
优点:恢复快
缺点:两次RDB之间,会造成数据的丢失
默认禁用 appendonly yes
生成AOF的策略
# appendfsync always 每个操作都记录日志:最安全,性能最差
appendfsync everysec 每秒记录一次
# appendfsync no 由操作系统决定什么时候写日志
no-appendfsync-on-rewrite no 当执行日志重写的时候,停止日志写入
触发日志重写的时机:
auto-aof-rewrite-percentage 100 日志文件比上次重写的时候大小超过了1倍
auto-aof-rewrite-min-size 64mb 日志文件超过64M
什么是AOF的重写:rewrite
将内存中的key逆向生成命令,如同一个可以,反复操作了100次,aof文件会记录100次操作,这样会导致AOF文件过大
例如:
经过重写后,直接执行: set age 100
AOF优点:保证数据的安全
AOF缺点:恢复效率低
结合RDB和AOF实现Redis的持久化:类似Oracle中:完全备份、增量备份
如果RDB和AOF都有,默认使用AOF进行恢复
可在同一台机器上实现, 只是启动多个redis, 读取压力大的情况下使用
是主从结构,就存在单点故障的问题
作用:(1)实现读写分离:默认:主节点负责写,从节点(s)负责读,多个从节点
(2)实现任务分离:主节点不再负责生产RDB和AOF文件,由从节点产生
架构:2种
(1)星型模型 从节点地位一致,效率较高,但是实现Ha比较麻烦
(2)线型模型 实现Ha简单,效率低,日志需要依次传递
配置:
主节点:关闭RDB 和AOF
#save 900 1
#save 300 10
#save 60 10000
appendonly no (AOF关闭)
从节点:开启RDB和AOF
参数:slaveof 配置主节点的地址
从节点1:
port 6380
dbfilename dump6380.rdb
appendfilename "appendonly6380.aof"
slaveof localhost 6379
从节点2:
port 6381
dbfilename dump6381.rdb
appendfilename "appendonly6381.aof"
slaveof localhost 6379
哨兵接受主节点的心跳信息,当主节点宕机后,将一从节点变成新的主节点,将其他从节点连接到新的主节点
Redis 2.4以后的版本中提出,Redis 2.4以前,使用ZooKeeper实现Redis HA
以:星型模型为例
#启动三个redis实例
#哨兵核心配置文件:sentinel.conf
#参数:
port 26379 端口号
#sentinel monitor ---> 配置哨兵监视对象,几个哨兵
主节点别名 主节点IP 主节点端口 几个哨兵(一般2个哨兵)
sentinel monitor mymaster 127.0.0.1 6379 1
#sentinel auth-pass #如果主节点配置了密码,哨兵链接主节点的密码
#sentinel down-after-milliseconds
sentinel down-after-milliseconds mymaster 30000 #如果30秒没有收到主节点的心跳,进行HA的切换
sentinel parallel-syncs mymaster 1 #这个参数一定不能太大,选举新的主节点后,允许同时接连的从节点的个数
# Default is 3 minutes. 如果3分钟内,HA的切换没有完成,就失败
sentinel failover-timeout mymaster 180000
#启动哨兵
bin/redis-sentinel conf/sentinel.conf
配置从节点位置,客户端访问的是代理,代理按照路由规则进行转发, 可以按照配置的权重进行分配
按照路由规则,转发给后台的各个Redis服务器,再原路返回。该方案很好的解决了单个Redis实例承载能力的问题。
安装
./configure --prefix=/root/training/proxy
make
make install
#拷贝一个配置文件
cp ~/tools/nutcracker-0.3.0/conf/nutcracker.yml conf/
#检查配置文件是否正确
sbin/nutcracker -t conf/nutcracker.yml
#启动代理服务器
./nutcracker -d -c conf/nutcracker.yml
是Redis提供的分布式存储的解决方案,去中心化(没有中心节点),分布式的存储
Redis Cluster体系架构
根据存入的key进行hash运算,放入到对应的slot当中!每个slot都由一个Redis群来负责存储,每个Redis群负责的slot个数是均分的,总共16383个slot;每个Redis群都由主节点和从节点构成,主节点死亡后 从节点变为主节点
安装部署:
#准备工作:安装ruby环境---> 部署Redis Cluster
yum install ruby
#还要安装Ruby访问Redis的接口
gem instal redis-3.0.5.gem
#方式一:手动部署(6个节点)
#规划:主节点:6379 6380 6381
# 从节点:6382 6383 6384
#参数:以6379为例
daemonize yes
port 6379
cluster-enabled yes
cluster-config-file nodes/nodes-6379.conf
cluster-node-timeout 15000
dbfilename dump6379.rdb
appendonly yes
appendfilename "appendonlyi6379.aof"
bin/redis-trib.rb create --replicas 1 192.168.157.111:6379 192.168.157.111:6380 192.168.157.111:6381 192.168.157.111:6382 192.168.157.111:6383 192.168.157.111:6384
#--replicas 1参数:副本,表示一个主节点由一个从节点
#测试:
bin/redis-cli -c -p 6379 #-c表示链接集群
#方式二:自动部署(6个节点)
#将源码的utils/create-cluster目录下,将create-cluster拷贝到安装目录的bin目录下
#修改create-cluster命令的路径
#启动和创建Redis集群
bin/create-cluster start # ----> 启动6个Redis的实例
bin/create-cluster create #----> 创建Redis Cluster
使用cluster
命令 |
说明 |
info |
打印集群的信息。 |
nodes |
列出集群当前已知的所有节点(node)的相关信息。 |
meet |
将ip和port所指定的节点添加到集群当中。 |
addslots |
将一个或多个槽(slot)指派(assign)给当前节点。 |
delslots |
移除一个或多个槽对当前节点的指派。 |
slots |
列出槽位、节点信息。 |
slaves |
列出指定节点下面的从节点信息。 |
replicate |
将当前节点设置为指定节点的从节点。 |
saveconfig |
手动执行命令保存保存集群的配置文件,集群默认在配置修改的时候会自动保存配置文件。 |
keyslot |
列出key被放置在哪个槽上。 |
flushslots |
移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。 |
countkeysinslot |
返回槽目前包含的键值对数量。 |
getkeysinslot |
返回count个槽中的键。 |
setslot |
将槽指派给指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽,然后再进行指派。 |
setslot |
将本节点的槽迁移到指定的节点中。 |
setslot |
从 node_id 指定的节点中导入槽 slot 到本节点。 |
setslot |
取消对槽 slot 的导入(import)或者迁移(migrate) |
failover |
手动进行故障转移。 |
forget |
从集群中移除指定的节点,这样就无法完成握手,过期时为60s,60s后两节点又会继续完成握手。 |
reset [HARD|SOFT] |
重置集群信息,soft是清空其他节点的信息,但不修改自己的id,hard还会修改自己的id,不传该参数则使用soft方式。 |
count-failure-reports |
列出某个节点的故障报告的长度。 |
SET-CONFIG-EPOCH |
设置节点epoch,只有在节点加入集群前才能设置。 |