redis事务
redis是单线程来处理client请求的,保证由一个client发起的请求会连续执行,不会插入其他client的命令。
使用 multi 开启事务,exec进行事物的提交。每当发出一个命令时,redis会将命令放到一个队列中,直到exec命令,将队列中的命令依次执行。当队列中的命令发生异常是,并不会进行事务的回滚,这点和关系数据库不太相同。
discard可以中断事务,清空事务的队列。
CAS: check and set,使用的是乐观锁机制。
当某个被监视的key在事务提交之前进行了修改,则跳出事务,并回滚。
jedis.set("name","init"); // name = init
jedis.watch("name");
jedis.append("name", "append"); // name = initappend
Transaction ta = jedis.multi();
ta.set("name", "modify");
ta.exec(); //name = initappend
name的值在事务中的修改没有生效
redis 的pipeline
redis是一个 cs模式的 tcp server,使用和 http类似的请求响应协议。一个 client可以通过一个 socket连接发起多个请求命令。每个请求命令发出后 client 通常 会阻塞并等待 redis 服务处理, redis 处理完后请求命令后会将结果通过响应报文返回给 client。但是一对一的太耗费时间,因此可以将多个命令打包到一个报文请求中,并由一个报文返回。节省时间。需要注意到是用 pipeline 方式打包命令发送, redis 必须在处理完所有命令前先缓存起所有命令的处理结果。打包的命令越多,缓存消耗内存也越多。所以并是不是打包的命令越多越好。具体多少合适需要根据具体情况测试@Test
public void test01() {
Jedis jedis = new Jedis("localhost", 6379);
jedis.set("num1", "0");
Long startTime = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
jedis.incr("num1");
}
Long endTime = System.currentTimeMillis();
System.out.println("没有使用管道的时间:"+ (endTime - startTime));
jedis.quit();
}
@Test
public void test02() {
Jedis jedis = new Jedis("localhost", 6379);
Pipeline pipe = jedis.pipelined();
jedis.set("num1", "0");
Long startTime = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
pipe.incr("num2");
}
Long endTime = System.currentTimeMillis();
System.out.println("使用管道的时间:"+ (endTime - startTime));
}
结果: 没有使用管道的时间:1155
使用管道的时间:34
使用管道的速度快很多
redis订阅模式
发布订阅(pub/sub)是一种消息通信模式,主要的目的是解耦消息发布者和消息订阅者之间的耦合,这点和设计模式中的观察者模式比较相似。 pub /sub 不仅仅解决发布者和订阅者直接代码级别耦合也解决两者在物理部署上的耦合。 redis 作为一个 pub/sub server,在订阅者和发布者之间起到了消息路由的功能。订阅者可以通过 subscribe和 psubscribe命令向 redis server订阅自己感兴趣的消息类型,redis将消息类型称为通道(channel)。当发布者通过 publish命令向 redis server发送特定类型的消息时。订阅该消息类型的全部 client 都会收到此消息。这里消息的传递是多对多的。一个 client 可以订阅多个 channel,也可以向多个 channel 发送消息数据持久化
Redis中数据存储模式有2种:cache-only,persistence
cache-only即只做为“缓存”服务,不持久数据,数据在服务终止后将消失,此模式下也将不存在“数据恢复”的手段,是一种安全性低/效率高/容易扩展的方式;
persistence即为内存中的数据持久备份到磁盘文件,在服务重启后可以恢复,此模式下数据相对安全。
EDB,Snapshotting 快照,redis默认方式。
使用save和bgsave进行快照的持久化。save命令会将使用主进程来进行持久化,会将当前进程阻塞。bgsave是创建子进程来完成快照的持久化。保存的文件名为dump.rdb。
save 100 1 表示如果在100秒内有一个key值被修改,则进行快照保存
AOF(Append Only File)
在使用AOF持久化方式时,每进行一个写操作时,命令通过write函数追加到文件中(默认是 appendonly.aof),redis重启可以通过文件来执行命令来进行恢复。
开启方式:在redis配置文件中进行设置即可。
appendonly yes //启用 aof 持久化方式
持久化模式:
# appendfsync always //每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,
不推荐使用
appendfsync everysec //每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
# appendfsync no //完全依赖 os,性能最好,持久化没保证
bgrewriteaof 压缩aof文件,