redis的消息订阅、pipeline管道命令、事务、EX过期时间、缓存LRU

Redis 管道(Pipelining)

Redis 管道(Pipelining):一次请求/响应服务器能实现处理新的请求即使旧的请求还未被响应。这样就可以将多个命令发送到服务器,而不用等待回复,最后在一个步骤中读取该答复。

管道的作用,降低通信成本。

linux下 : echo -e "set k2 100\n get k2" | nc localhost 6379

\n 会自动识别为多条命令。

例如:启动的时候需要冷加载大量的数据到redis中。

Pub/Sub 消息订阅

publish : 推送

subscribe : 订阅

PUBLISH number1 "get is reply": 推送消息 "get is reply" 到 number1频道

开启两个客户端。A未进行订阅,B先于发送,这时A端接收不到,因为没进行任何的订阅。

A进行订阅 number1 ,B进行发送,,可以看到已经接收成功了。

订阅多个频道

PSUBSCRIBE 通配符订阅

PSUBSCRIBE number* : 订阅 number 开头的所有频道

 

事务相关命令

MULTI、EXEC、DISCARD、WATCH

MULTI:标记一个事务块的开始。 随后的指令将在执行EXEC时作为一个原子执行。

DISCARD:取消事务

WATCH:监控一个或多个key,如果在执行事务前这些key被更改,则事务被打断。先watch key,然后 multi,然后exec。

为什么 Redis 不支持回滚(roll back)

如果你有使用关系式数据库的经验, 那么 “Redis 在事务失败时不进行回滚,而是继续执行余下的命令”这种做法可能会让你觉得有点奇怪。

以下是这种做法的优点:

  • Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。
  • 因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速。

1. 不支持事务回滚所以redis比较快

2. redis只会因为错误的语法而失败,而这些编程中的错误应该在被开发中发现,而不应该出现在生产中。

1. A端查询keys 为空,B端开启事务MULTI,set k1 ,k2。这时A端继续get k1,但是没查询到。因为B端没有EXEC提交事务。

2. B端提交,A端查询。

事务处理顺序

B端先开启事务,设置k1 111,A端查询k1,开启事务,设置k1 999,A端提交事务。查询k1。B端提交事务。

exec 谁先提交算谁的。不会回滚。

EXPIRE key seconds

ex

set k1 ddd ex 5 : 设置 k1  过期时间为 5秒, EX 后面跟秒

修改k1 的时候不会延长过期时间,但是会影响使过期时间失效

EXPIREAT

EXPIREAT k1 1592354325: 设置k1 在某个时间戳的时候过期。

persist key : 清除某个key的过期时间

ttl

ttl k1 查看过期时间(秒)。 返回 -2 :过期,-1 :永不过期,大于0则是剩余的有效期秒数

px

 set k2 aaa px 500000 : 设置过期时间 px 后面跟毫秒

nx

当则会个key不存在的时候也可以成功,即没有就新增

xx

当这个key不存在的时候失败,即key必须存在

Redis如何淘汰过期的keys

Redis keys过期有两种方式:被动和主动方式。

当一些客户端尝试访问它时,key会被发现并主动的过期。

当然,这样是不够的,因为有些过期的keys,永远不会访问他们。 无论如何,这些keys应该过期,所以定时随机测试设置keys的过期时间。所有这些过期的keys将会从密钥空间删除。

具体就是Redis每秒10次做的事情:

  1. 测试随机的20个keys进行相关过期检测。
  2. 删除所有已经过期的keys。
  3. 如果有多于25%的keys过期,重复步奏1.

过期判断原理:

1.被动访问时判定。即在访问时发现过期了才做判定。

2.周期轮询判定(增量)。即使用上方的淘汰机制随机判定。

目的:稍微牺牲下内存,但是保住了redis性能为王。

将redis当做使用LRU算法的缓存来使用

回收策略

当maxmemory限制达到的时候Redis会使用的行为由 Redis的maxmemory-policy配置指令来进行配置

策略:

当作为数据库的时候不推荐使用,否则会造成数据丢失

  • noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但DEL和几个例外)

作为缓存的时候可以考虑(前二)

  • allkeys-lru: 尝试回收所有数据中最少使用的键(LRU),使得新添加的数据有空间存放。释放使用不多的键
  • volatile-lru: 尝试回收已经过期的数据中最少使用的键(LRU),使得新添加的数据有空间存放。多久没使用
  • allkeys-random: 回收所有数据中随机的键使得新添加的数据有空间存放。太随意不推荐
  • volatile-random: 回收过期的数据中随机的键使得新添加的数据有空间存放。太随意不推荐
  • volatile-ttl: 回收在过期集合的键,将要过期的键,存活时间(TTL)较短的键,使得新添加的数据有空间存放。 时间成本太高

redis作为数据库/缓存的区别

1.key的有效期。发生写,会影响过期时间倒计时,且redis不能延长定时。

2.内存是有限的,随着访问的变化应该淘汰掉冷数据。

管道批量获取数据并清除

/**
         * 批量获取数据并清除
         */
        List<Person> people = redisTemplate.executePipelined(new SessionCallback<List>() {
            @Override
            public <K, V> List<Person> execute(RedisOperations<K, V> operations) throws DataAccessException {
                operations.multi();
                List<Person> people = redisTemplate.opsForList().range("lists",0,500);
                redisTemplate.opsForList().trim("lists",0,500);
                return people;
            }
        });

https://cloud.tencent.com/developer/article/1554080

redis中文站 : http://redis.cn/topics/pipelining.html

猜你喜欢

转载自blog.csdn.net/dandanforgetlove/article/details/106240961
今日推荐