系列文章目录
Redis01 基础及安装
Redis02-架构及简单使用
Redis03-数据类型:应用及实操
Redis04-进阶使用(管道、发布/订阅)
Redis05-进阶使用(事务)
Redis06-进阶使用(过期 expire)
Redis07-RDB和AOF
一、redis管道
一次请求/响应服务器能实现处理新的请求即使旧的请求还未被响应。这样就可以将多个命令发送到服务器,而不用等待回复,最后在一个步骤中读取该答复。这就是管道(pipelining)技术。例如许多POP3协议已经实现支持这个功能,大大加快了从服务器下载新邮件的过程。
使用管道发送命令时,服务器将被迫回复一个队列答复,占用很多内存。所以,如果你需要发送大量的命令,最好是把他们按照合理数量分批次的处理,例如10K的命令,读回复,然后再发送另一个10k的命令,等等。这样速度几乎是相同的,但是在回复这10k命令队列需要非常大量的内存用来组织返回数据内容。
实操
1.安装nc
yum install nc -y
2.通过nc连接redis
nc localhost 6379
3.通过echo向nc发送指令
echo -e "set k2 99\nincr k2\n get k2" |nc localhost 6379
二、发布订阅(Pub/Sub)
订阅,取消订阅和发布实现了发布/订阅消息范式(引自wikipedia),发送者(发布者)不是计划发送消息给特定的接收者(订阅者)。而是发布的消息分到不同的频道,不需要知道什么样的订阅者订阅。订阅者对一个或多个频道感兴趣,只需接收感兴趣的消息,不需要知道什么样的发布者发布的。这种发布者和订阅者的解耦合可以带来更大的扩展性和更加动态的网络拓扑。
从宏观上来讲,Redis的发布/订阅模式具有如下特点:
客户端执行订阅以后,可以继续订阅(SUBSCRIBE或者PSUBSCRIBE),取消订阅(UNSUBSCRIBE或者PUNSUBSCRIBE),客户端将阻塞直到订阅通道上发布消息的到来。
发布的消息在Redis系统中不存储。因此,必须先执行订阅,再等待消息发布。
订阅的通道名称支持glob模式匹配。如果客户端同时订阅了glob模式的通道和非glob模式的通道,并且名称存在交集,则对于一个发布的消息,该执行订阅的客户端接收到两个消息。
help @pubsub
## 起一个cli 订阅 ooxx 这个通道
127.0.0.1:6379> SUBSCRIBE ooxx
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "ooxx"
3) (integer) 1
1) "message"
2) "ooxx"
3) "hello"
## 另起一个cli 发布消息
127.0.0.1:6379> PUBLISH ooxx hello
(integer) 1
三、基于pub/sub讨论聊天软件的架构
声明:这只借聊天的场景探讨redis的应用,人家真正的架构肯定比这优雅的多~
在聊天软件(比如某信)中,数据分为两种,一种是实时数据,比如我们正在聊天的内容;一种是历史性的数据,向上翻可以翻到几天前的,这里还可以细分为几天内的和更早的。
首先,要明白数据的全量一定是在数据库里的。但是,如果这么多用户、这么多群、这么多记录都去访问数据库,那么数据库的压力肯定很大。所以一般需要Redis作缓存。(这里的缓存是为了解决数据的读的请求)
客户端取消息:
1、实时性数据:我们可以通过发布/订阅解决。
2、3天之内的数据:首先消息记录是有时间顺序的,而且需要做窗口的控制,我们可以通过sorted_set来存数据。(把时间作为分值,把消息作为元素,可以通过zremrangebyscore指令,把日期最小的移除)
3、更老的数据,到数据库里取
客户端存数据:
1、实时数据,从发布/订阅上发布数据
2、同时,把数据发给kafka,让kafka去存数据库(如果每个客户端都去自己实现写数据库,那么对数据库的压力会很大)
3、把消息写进sorted set里面
但是我们现在的架构还是非常简陋,由于在写数据的时候是客户端单调的调数据,那么客户端发布完了,还没往zset中写的时候挂掉了,该怎么办呢?那么我们需要对redis进行拆分。
(未完待续,具体细节有空再写,可以先看图)