redis是一个NoSQL数据库,其在当今的互联网公司有着和传统数据库相辅相成的角色。今天来对其进行小结一下。
在写这个小结时,我已工作两年了,也就是说已经使用了两年redis(虽然公司内部使用的是运维同学的r2m集群,在京东的同学应该都知道,其底层就是redis)。所以这里不会说怎么起下载安装了,介绍redis的五种数据类型了。这在网上一查一大把,这都是最基础的使用了 string list set zset hash。
比起常用的数据操纵命令,这里主要说说redis的事务操纵,redis的发布订阅(项目中一直在用,可以和消息中间件对比学习一下),以及redis的分布式锁的使用,最后顺便说说pipline的使用。学习任何一个技术,首先扒拉一下官方文档。
Programming with Redis
The full list of commands implemented by Redis, along with thorough documentation for each of them.
Pipelining: Learn how to send multiple commands at once, saving on round trip time.
Redis Pub/Sub: Redis is a fast and stable Publish/Subscribe messaging system! Check it out.
Redis Lua scripting: Redis Lua scripting feature documentation.
Debugging Lua scripts: Redis 3.2 introduces a native Lua debugger for Redis scripts.
Memory optimization: Understand how Redis uses RAM and learn some tricks to use less of it.
Expires: Redis allows to set a time to live different for every key so that the key will be automatically removed from the server when it expires.
Redis as an LRU cache: How to configure and use Redis as a cache with a fixed amount of memory and auto eviction of keys.
Redis transactions: It is possible to group commands together so that they are executed as a single transaction.
Mass insertion of data: How to add a big amount of pre existing or generated data to a Redis instance in a short time.
Partitioning: How to distribute your data among multiple Redis instances.
Distributed locks: Implementing a distributed lock manager with Redis.
Redis keyspace notifications: Get notifications of keyspace events via Pub/Sub (Redis 2.8 or greater).
Creating secondary indexes with Redis: Use Redis data structures to create secondary indexes, composed indexes and traverse graphs.
上述内容来自redis的官方文档:
1.redis是所有实现的命令列表。
2.redis的pipline
3.redis的pub/sub命令
4.redis的lua脚本
5.redis debug
6.redis内存优化
7.redis的过期
8.redis的lurkey淘汰算法
9.redis的事务
10.redis的大数写入
11.redis的数据在集群上的分片
13.redis分布式锁
。。。
pipline
using piplining to speedup redis queryies
官方第一句话说的就是,使用pipline的目的就是为了加快查询。redis的本质是一个tpc的client/server模型,也就是说,一个查询请求到达服务端了,然后等待服务端处理了,然后把数据再返回给客户端。这个从请求发出到接收到服务端返回的消息这段时间就是往返时延。
pipline就是跳过请求-等待-响应的这种模式,即使你一个请求没有被处理完也可以继续发请求,这样就是在客户端不等待响应的情况下可以继续向服务端发送请求。在最终给你返回你本次这批请求的结果。
Client: INCR X
Client: INCR X
Client: INCR X
Client: INCR X
Server: 1
Server: 2
Server: 3
Server: 4
这种情况下就不需要为每次请求都等待了,缩短了往返延时。
pipline不仅仅是在往返延时上进行改善,从服务器的角度也能大量的降低cpu的使用率,比如,你有1000个请
求,原来需要1000次,现在只需要一次了。
try {
jedis = new Jedis("10.10.224.44", 6379);
Pipeline pipline = jedis .pipelined();
for(int i =0; i<1000; i++){
pipline .incr("hello");
}
pl.sync();
} catch (Exception e) {
...
}
pub/sub
redis的pub/sub其实就是一个消息的发布和监听的方式,把消息的发布者和接收者进行解耦。
实际使用案例:
在用lucene做搜索的时候,由于生产索引只是在一台上生产,所以,需要把索引从生产的这台机器上分别放在每一个实例的机器上,那么问题来了,该怎么告诉那些机器我生产好了呢?这里就可以使用这个命令。
if(索引生产出来了)
then pub(在指定的频道发布了一个消息)
继承了jedis subscribe
if(消息来了)
then 我就去你的机器上复制了
在现在消息中间件大行其道的环境下,还是不推荐使用这种方式来进行小心通讯,消息对于发布者来说是发布即消失,订阅者需要有线程一直来监听消息的发布。使用mq消息来替代这种方式,
redis 事务
在一个队列中,一次性的,顺序的,排它的执行一系列命令。
DISCARD
EXEC
MULTI
UNWATCH
WATCH
discard 放弃本次事务
multi 开启事务,通常返回一个OK(open session)开启事务后,每次一次操作都是入队,知道exec,所有队列的命令才会被提交的。
exec 执行事务(commit)
watch 监视一个或者多个key
unwatch 取消watch对所有key的监视
multi --> set a 1 set b 2 set c 3 --->exec
watch特别说明。比如我watch的时候,用户的账户余额100块,在你自己处理一系列后,还是100块,提交的时候就没问题。如果在这个watch期间被别人修改过了,那么在watch提交会告诉你失败了。
redis对事务的支持是部分支持的,因为它是先吧所有命令放在执行队列中,只有执行的时候才知道能不能执行成功:
multi -->set a aa incr a set b 1--exec
这个命令执行完成后,只有b=1能成功,因为a 的value string类型的无法进行加一操作,但是redis在未执行的时候是不知道的,所以只有在执行了,才知道是败了,所以第一条命令失败了但是第二条set b 1是合法的,是能执行成功的。
所以,redis对事务的支持是部分支持。