redis超详细整理

Redis复习与面试题

学习

概述:

一、几种数据类型详解

1、String
[root@localhost src]# redis-cli 
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> select 1  #(切换数据库)
OK
127.0.0.1:6379[1]> get name  #(获取当前数据库名)
(nil)
127.0.0.1:6379[1]> dbsize  #(获取数据库大小)
(integer) 0
127.0.0.1:6379[1]> 
127.0.0.1:6379> mset name ll age 11 address yibin  #mset key1 value1 key2 value2....设置多个key-value
OK
127.0.0.1:6379> mget name age address  #mget key1 key2 key3 获取多个value
1) "ll"
2) "11"
3) "yibin"
127.0.0.1:6379> getset birthday 9/10
(nil)
127.0.0.1:6379> get birthday
"9/10"
127.0.0.1:6379> 
127.0.0.1:6379> getset birthday 9/10  #将给定 key 的值设为 value ,并返回 key 的旧值(old value)。
(nil)
127.0.0.1:6379> get birthday
"9/10"
127.0.0.1:6379> setnx name lm #若key不存在才设置
(integer) 0
127.0.0.1:6379> get name 
"ll"
127.0.0.1:6379> setnx money 20
(integer) 1
127.0.0.1:6379> get money
"20"
127.0.0.1:6379> setex name 30 lm #设置key 并设置过期时间
OK
127.0.0.1:6379> ttl name  #查看还有多久过期
(integer) 24
127.0.0.1:6379> ttl name
(integer) 22
2.List
127.0.0.1:6379> lpush stu 1  #将看成一个栈往左边插入值(头部),往底部输送值。压栈,先插进后输出,所以5为开始元素
(integer) 1
127.0.0.1:6379> lpush stu 2  #将一个或多个值插入到列表头部
(integer) 2
127.0.0.1:6379> lpush stu 3
(integer) 3
127.0.0.1:6379> lpush stu 4 5
(integer) 5
127.0.0.1:6379> lrange 0 -1
(error) ERR wrong number of arguments for 'lrange' command
127.0.0.1:6379> lrange stu 0 -1  #获取列表指定范围内的元素 lrange key start end
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
127.0.0.1:6379> 


127.0.0.1:6379> llen stu  #查看元素多少个
(integer) 5
127.0.0.1:6379> lindex stu 0  #按元素索引查看集合元素
"5"
127.0.0.1:6379> lrem stu 0 1 #删除集合指定值  	LREM key count value
(integer) 1
127.0.0.1:6379> llen stu  #获取集合长度 llen key
image-20200912162853885

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-znPirpbw-1600600407442)(C:\Users\Jakelong\AppData\Roaming\Typora\typora-user-images\image-20200912164042389.png)]

·他实际上是一个链表,before Node after , left , right都可以插入值
·如果key不存在,创建新的链表
·如果key存在,新增内容
·如果移除了所有值,空链表,也代表不存在!
·在两边插入或者改动值,效率最高!中间元素,相对来说效率会低一点~
消息排队!消息队列( Lpush Rpop ),栈( Lpush Lpop ) !

3.set
127.0.0.1:6379> sadd myset 1  #添加一个元素
(integer) 1
127.0.0.1:6379> sadd myset 2
(integer) 1
127.0.0.1:6379> sadd myset 3
(integer) 1
127.0.0.1:6379> smembers myset #查看set集合所含元素
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> sismember myset 1 #查看set集合有误1这个元素
(integer) 1
127.0.0.1:6379> 
127.0.0.1:6379> smembers myset  #查看myset集合所含元素
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> scard myset  #查看myset集合所含元素 ‘个数’
(integer) 3
127.0.0.1:6379> sadd herset 1 2 #往herset集合添加1 2两个元素
(integer) 2
127.0.0.1:6379> smembers herset
1) "1"
2) "2"
127.0.0.1:6379> sdiff myset herset #查看myset与herset集合差别元素有哪些,第一个为参照,看有哪些是第一个有第二个没有的
1) "3"
127.0.0.1:6379> sadd herset 4 5 6 7
(integer) 4
127.0.0.1:6379> sdiff myset herset
1) "3"
127.0.0.1:6379> sdiff herset myset
1) "4"
2) "5"
3) "6"
4) "7"
127.0.0.1:6379> 
127.0.0.1:6379> sunion myset herset #查看并集
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"

127.0.0.1:6379> srandmember myset  #随机返回集合中一个数或则多个数
"1"
127.0.0.1:6379> srandmember myset
"2"
127.0.0.1:6379> spop myset  #随机删除集合中一个数并返回这个删除的数

4.zset

Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

有序集合的成员是唯一的,但分数(score)却可以重复。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 2的32次方 - 1 (4294967295, 每个集合可存储40多亿个成员)。

127.0.0.1:6379> zadd myset 1 redis  #往集合添加一个或则多个成员  若已经存在,则更新ZADD key score1 member1 [score2 member2]
(integer) 1
127.0.0.1:6379> zadd myset 1 mysql 
(integer) 1
127.0.0.1:6379> zadd myset 1 mongodb
(integer) 1
127.0.0.1:6379> zcard myset #获取有序集合的成员数
(integer) 3
127.0.0.1:6379> zincrby myset 1 redis #有序集合中对指定成员的分数加上增量 increment
"2"
127.0.0.1:6379> zrange myset 0 -1 #列出范围内的集合的成员
1) "mongodb"
2) "mysql"
3) "redis"
127.0.0.1:6379> zrange myset 0 -1 withscores #带分数
1) "mongodb"
2) "1"
3) "mysql"
4) "1"
5) "redis"
6) "2"
127.0.0.1:6379>
127.0.0.1:6379> zcount myset 1 3  #获取区间分数的成员数 	ZCOUNT key min max
(integer) 3
127.0.0.1:6379> zrange myset 0 1 
1) "redis"
2) "mysql"
127.0.0.1:6379> zrank myset mysql
(integer) 1
127.0.0.1:6379> zrank myset redis #返回指定成员索引
(integer) 0
127.0.0.1:6379> zrank myset ll
(integer) 3
127.0.0.1:6379> zrange myset 0 -1
1) "redis"
2) "mysql"
3) "mongdb"
4) "ll"
127.0.0.1:6379> zrem myset ll #移除指定元素
(integer) 1
127.0.0.1:6379> zcard myset #获取集合成员数
(integer) 3
127.0.0.1:6379> zrank myset ll
(nil)
127.0.0.1:6379> 

二、事务

Redis单条命令式保存原子性的,但是事务不保证原子性!

开启事务|————一组命令集合(队列中)————| 提交事务

  • 注:事务期间,语法出错事务取消,若运行期间出错,不会影响其他命令
127.0.0.1:6379> multi  #开启事务
OK
127.0.0.1:6379> set name ll  #将该命令入队
QUEUED
127.0.0.1:6379> set age 19
QUEUED
127.0.0.1:6379> get name
QUEUED
127.0.0.1:6379> incrby name 1  #将name值增加1  因为name值为字符串 不能加1,所以运行时会出错,但是redis不具有原子性,运行时出错不会影响其他命令的执行
QUEUED
127.0.0.1:6379> exec  #提交事务
1) OK
2) OK
3) "ll"
4) (error) ERR value is not an integer or out of range
127.0.0.1:6379> 

三、springboot整合reids

四、redis配置文件详解

注:redis设置密码

config get requirepass #查看密码

config set requirepass 123456 #设置密码

auth password

127.0.0.1:6379> config get requirepass
(error) NOAUTH Authentication required.
127.0.0.1:6379> keys *
(error) NOAUTH Authentication required.
127.0.0.1:6379> set name 1
(error) NOAUTH Authentication required.
127.0.0.1:6379> auth 123456  #获取操作reids权限
OK
127.0.0.1:6379> keys *
1) "stu"
127.0.0.1:6379>

2.第二种方式 (永久方式)
需要永久配置密码的话就去redis.conf的配置文件中找到requirepass这个参数,如下配置:

修改redis.conf配置文件

# requirepass foobared
requirepass 123 指定密码123

保存后重启redis就可以了

####################################回归正题#############################################################

配置文件详解

###################################  NETWORK ###################################
# 指定 redis 只接收来自于该IP地址的请求,如果不进行设置,那么将处理所有请求
bind 127.0.0.1

#是否开启保护模式,默认开启。要是配置里没有指定bind和密码。开启该参数后,redis只会本地进行访问,
拒绝外部访问。要是开启了密码和bind,可以开启。否则最好关闭,设置为no
protected-mode yes

#redis监听的端口号
port 6379

#此参数为设置客户端空闲超过timeout,服务端会断开连接,为0则服务端不会主动断开连接,不能小于0
timeout 0

#是否在后台执行,yes:后台运行;no:不是后台运行
daemonize yes

#redis的进程文件
pidfile /var/run/redis/redis.pid

#指定了服务端日志的级别。级别包括:debug(很多信息,方便开发、测试),verbose(许多有用的信息,
但是没有debug级别信息多),notice(适当的日志级别,适合生产环境),warn(只有非常重要的信息)
loglevel notice

#指定了记录日志的文件。空字符串的话,日志会打印到标准输出设备。后台运行的redis标准输出是/dev/null
logfile /usr/local/redis/var/redis.log

#数据库的数量,默认使用的数据库是0。可以通过”SELECT 【数据库序号】“命令选择一个数据库,序号从0开始
databases 16


###################################  SNAPSHOTTING -snapshotting ###################################
 
#RDB核心规则配置 save <指定时间间隔> <执行指定次数更新操作>,满足条件就将内存中的数据同步到硬盘
中。官方出厂配置默认是 900秒内有1个更改,300秒内有10个更改以及60秒内有10000个更改,则将内存中的
数据快照写入磁盘。
若不想用RDB方案,可以把 save "" 的注释打开,下面三个注释
#   save ""
save 900 1  #持久化  若900s内有一个key改变就就行持久化
save 300 10
save 60 10000
 
#当RDB持久化出现错误后,是否依然进行继续进行工作,yes:不能进行工作,no:可以继续进行工作,可以通
过info中的rdb_last_bgsave_status了解RDB持久化是否有错误
stop-writes-on-bgsave-error yes
 
#配置存储至本地数据库时是否压缩数据,默认为yes。Redis采用LZF压缩方式,但占用了一点CPU的时间。若关闭该选项,
但会导致数据库文件变的巨大。建议开启。
rdbcompression yes
 
#是否校验rdb文件;从rdb格式的第五个版本开始,在rdb文件的末尾会带上CRC64的校验和。这跟有利于文件的
容错性,但是在保存rdb文件的时候,会有大概10%的性能损耗,所以如果你追求高性能,可以关闭该配置
rdbchecksum yes
 
#指定本地数据库文件名,一般采用默认的 dump.rdb
dbfilename dump.rdb
 
#数据目录,数据库的写入会在这个目录。rdb、aof文件也会写在这个目录
dir /usr/local/redis/var
 #################################  CLIENTS-clients #################################
# 设置能连上redis的最大客户端连接数量。默认是10000个客户端连接。由于redis不区分连接是客户端连接还
是内部打开文件或者和slave连接等,所以maxclients最小建议设置到32。如果超过了maxclients,redis会给
新的连接发送’max number of clients reached’,并关闭连接
# maxclients 10000
#######################    MEMORY MANAGEMENT    ##########################
redis配置的最大内存容量。当内存满了,需要配合maxmemory-policy策略进行处理。注意slave的输出缓冲区
是不计算在maxmemory内的。所以为了防止主机内存使用完,建议设置的maxmemory需要更小一些
maxmemory 122000000
#内存容量超过maxmemory后的处理策略。
#volatile-lru:利用LRU算法移除设置过过期时间的key。
#volatile-random:随机移除设置过过期时间的key。
#volatile-ttl:移除即将过期的key,根据最近过期时间来删除(辅以TTL)
#allkeys-lru:利用LRU算法移除任何key。
#allkeys-random:随机移除任何key。
#noeviction:不移除任何key,只是返回一个写错误。
#上面的这些驱逐策略,如果redis没有合适的key驱逐,对于写命令,还是会返回错误。redis将不再接收写请求,只接收get请求。写命令包括:set setnx setex append incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby getset mset msetnx exec sort。
# maxmemory-policy noeviction
# lru检测的样本数。使用lru或者ttl淘汰算法,从需要淘汰的列表中随机选择sample个key,选出闲置时间最长的key移除
# maxmemory-samples 5
# 是否开启salve的最大内存
# replica-ignore-maxmemory yes

https://blog.csdn.net/suprezheng/article/details/90679790

五、redis持久化

六、redis发布订阅

七、集群搭建

1、主从复制
  • 配从不配主 (slaveof ip port)
  • 读写分离——读是主读,写是仆写
  • 一主二仆
  • 薪火相传-主-从(主)-从(主)…
  • 反客为主
  • slaveof no one(让当前数据库停止与其他数据库同步,转为主数据库—不当仆人了,自己当老板)
2、哨兵模式
[root@localhost redis]# ./src/redis-cli -p 6379
127.0.0.1:6379> info replication
#Replication
role:slave   #仆人
master_host:127.0.0.1
master_port:6381
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:788909
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:4a6db5c73daf810c51fa362b540a16c6a3a73fba
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:788909
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:25173
repl_backlog_histlen:763737
127.0.0.1:6379> 
[root@localhost redis]# ./src/redis-cli -p 6380
127.0.0.1:6380> info replication
#Replication
role:slave  #仆人
master_host:127.0.0.1
master_port:6381
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:790257
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:4a6db5c73daf810c51fa362b540a16c6a3a73fba
master_replid2:8d05896f7cf6f0677d10638be555123c8e238998
master_repl_offset:790257
second_repl_offset:2630
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15shell
repl_backlog_histlen:790243
127.0.0.1:6380> 
[root@localhost redis]# ./src/redis-cli -p 6381
127.0.0.1:6381> info replication
# Replication
role:master  #主
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=791341,lag=0
slave1:ip=127.0.0.1,port=6379,state=online,offset=791341,lag=0
master_replid:4a6db5c73daf810c51fa362b540a16c6a3a73fba
master_replid2:8d05896f7cf6f0677d10638be555123c8e238998
master_repl_offset:791473
second_repl_offset:2630
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:791459
127.0.0.1:6381> 

开启哨兵模式

a、配置sentinel.conf 文件(必须同名)

sentinel monitor 名字 ip port 1(这个1代表主机挂了,由哨兵投票选举新的主机,得票多的上任)

3、复制原理
  • Slave启动成功连接到master后会发送一个sync同步命令
  • 全量复制:slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。(首次为全量)
  • 增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步。(其他时候执行一次命令,增量复制一次)
  • Master接到命令,启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,并完成一次完全同步
  • 但是只要是重新连接master,一次完全同步(全量复制)将被自动执行!我们的数据一定可以在从机中看到!

八、场景应用

1、限时秒杀
2、常规计数: 微博数, 粉丝数

利用string incr decr进行操作

3、存储部分变更数据,如用户信息

利用hash

4、显示最新的项目列表

下面这个语句常用来显示最新项目,随着数据多了,查询毫无疑问会越来越慢。

SELECT * FROM foo WHERE ... ORDER BY time DESC LIMIT 10   

在Web应用中,“列出最新的回复”之类的查询非常普遍,这通常会带来可扩展性问题。这令人沮丧,因为项目本来就是按这个顺序被创建的,但要输出这个顺序却不得不进行排序操作。类似的问题就可以用Redis来解决。比如说,我们的一个Web应用想要列出用户贴出的最新20条评论。在最新的评论边上我们有一个“显示全部”的链接,点击后就可以获得更多的评论。我们假设数据库中的每条评论都有一个唯一的递增的ID字段。我们可以使用分页来制作主页和评论页,使用Redis的模板,每次新评论发表时,我们会将它的ID添加到一个Redis列表:

LPUSH latest.comments <ID>   

我们将列表裁剪为指定长度,因此Redis只需要保存最新的5000条评论:

LTRIM latest.comments 0 5000 

每次我们需要获取最新评论的项目范围时,我们调用一个函数来完成(使用伪代码):

FUNCTION get_latest_comments(start, num_items):  
    id_list = redis.lrange("latest.comments",start,start+num_items - 1)  
    IF id_list.length < num_items  
        id_list = SQL_DB("SELECT ... ORDER BY time LIMIT ...")  
    END  
    RETURN id_list  
END 

​ 这里我们做的很简单。在Redis中我们的最新ID使用了常驻缓存,这是一直更新的。但是我们做了限制不能超过5000个ID,因此我们的获取ID函数会一直询问Redis。只有在start/count参数超出了这个范围的时候,才需要去访问数据库。

​ 我们的系统不会像传统方式那样“刷新”缓存,Redis实例中的信息永远是一致的。SQL数据库(或是硬盘上的其他类型数据库)只是在用户需要获取“很远”的数据时才会被触发,而主页或第一个评论页是不会麻烦到硬盘上的数据库了。

5、排行榜应用,取TOP N操作

这个需求与上面需求的不同之处在于,取最新N个数据的操作以时间为权重,这个是以某个条件为权重,比如按顶的次数排序,这时候就需要我们的sorted set出马了,将你要排序的值设置成sorted set的score,将具体的数据设置成相应的value,每次只需要执行一条ZADD命令即可。

热门,排行榜应用:

//将登录次数和用户统一存储在一个sorted set里
zadd login:login_times 5 1
zadd login:login_times 1 2
zadd login:login_times 2 3
//当用户登录时,对该用户的登录次数自增1
ret = r.zincrby("login:login_times", 1, uid)
//那么如何获得登录次数最多的用户呢,逆序排列取得排名前N的用户
ret = r.zrevrange("login:login_times", 0, N-1)

另一个很普遍的需求是各种数据库的数据并非存储在内存中,因此在按得分排序以及实时更新这些几乎每秒钟都需要更新的功能上数据库的性能不够理想。典型的比如那些在线游戏的排行榜,比如一个Facebook的游戏,根据得分你通常想要:

- 列出前100名高分选手

- 列出某用户当前的全球排名

这些操作对于Redis来说小菜一碟,即使你有几百万个用户,每分钟都会有几百万个新的得分。模式是这样的,每次获得新得分时,我们用这样的代码:

ZADD leaderboard  <score>  <username>

你可能用userID来取代username,这取决于你是怎么设计的。得到前100名高分用户很简单:

ZREVRANGE leaderboard 0 99

用户的全球排名也相似,只需要:

ZRANK leaderboard <username>
6、删除与过滤

我们可以使用LREM来删除评论。如果删除操作非常少,另一个选择是直接跳过评论条目的入口,报告说该评论已经不存在。 有些时候你想要给不同的列表附加上不同的过滤器。如果过滤器的数量受到限制,你可以简单的为每个不同的过滤器使用不同的Redis列表。毕竟每个列表只有5000条项目,但Redis却能够使用非常少的内存来处理几百万条项目。

7、按照用户投票和时间排序

排行榜的一种常见变体模式就像Reddit或Hacker News用的那样,新闻按照类似下面的公式根据得分来排序:score = points / time^alpha 因此用户的投票会相应的把新闻挖出来,但时间会按照一定的指数将新闻埋下去。下面是我们的模式,当然算法由你决定。模式是这样的,开始时先观察那些可能是最新的项目,例如首页上的1000条新闻都是候选者,因此我们先忽视掉其他的,这实现起来很简单。每次新的新闻贴上来后,我们将ID添加到列表中,使用LPUSH + LTRIM,确保只取出最新的1000条项目。有一项后台任务获取这个列表,并且持续的计算这1000条新闻中每条新闻的最终得分。计算结果由ZADD命令按照新的顺序填充生成列表,老新闻则被清除。这里的关键思路是排序工作是由后台任务来完成的。

8、处理过期项目

另一种常用的项目排序是按照时间排序。我们使用unix时间作为得分即可。 模式如下:

- 每次有新项目添加到我们的非Redis数据库时,我们把它加入到排序集合中。这时我们用的是时间属性,current_time和time_to_live。

- 另一项后台任务使用ZRANGE…SCORES查询排序集合,取出最新的10个项目。如果发现unix时间已经过期,则在数据库中删除条目。

9、计数

Redis是一个很好的计数器,这要感谢INCRBY和其他相似命令。我相信你曾许多次想要给数据库加上新的计数器,用来获取统计或显示新信息,但是最后却由于写入敏感而不得不放弃它们。好了,现在使用Redis就不需要再担心了。有了原子递增(atomic increment),你可以放心的加上各种计数,用GETSET重置,或者是让它们过期。例如这样操作:

INCR user:<id> EXPIRE  

你可以计算出最近用户在页面间停顿不超过60秒的页面浏览量,当计数达到比如20时,就可以显示出某些条幅提示,或是其它你想显示的东西。

9、特定时间内的特定项目

​ 另一项对于其他数据库很难,但Redis做起来却轻而易举的事就是统计在某段特点时间里有多少特定用户访问了某个特定资源。比如我想要知道某些特定的注册用户或IP地址,他们到底有多少访问了某篇文章。每次我获得一次新的页面浏览时我只需要这样做:

SADD page:day1:<page_id> <user_id> 

当然你可能想用unix时间替换day1,比如time()-(time()%3600*24)等等。 想知道特定用户的数量吗?只需要使用

SCARD page:day1:<page_id>

需要测试某个特定用户是否访问了这个页面?

SISMEMBER page:day1:<page_id>
10、查找某个值所在的区间(区间无重合) :(Sorted Set)

例如有下面两个范围,10-20和30-40

  • A_start 10, A_end 20
  • B_start 30, B_end 40

我们将这两个范围的起始位置存在Redis的Sorted Sets数据结构中,基本范围起始值作为score,范围名加start和end为其value值:

redis 127.0.0.1:6379> zadd ranges 10 A_start
(integer) 1
redis 127.0.0.1:6379> zadd ranges 20 A_end
(integer) 1
redis 127.0.0.1:6379> zadd ranges 30 B_start
(integer) 1
redis 127.0.0.1:6379> zadd ranges 40 B_end
(integer) 1

这样数据在插入Sorted Sets后,相当于是将这些起始位置按顺序排列好了。现在我需要查找15这个值在哪一个范围中,只需要进行如下的zrangbyscore查找:

redis 127.0.0.1:6379> zrangebyscore ranges (15 +inf LIMIT 0 1
1) "A_end"

这个命令的意思是在Sorted Sets中查找大于15的第一个值。(+inf在Redis中表示正无穷大,15前面的括号表示>15而非>=15)查找的结果是A_end,由于所有值是按顺序排列的,所以可以判定15是在A_start到A_end区间上,也就是说15是在A这个范围里。至此大功告成。

11、交集,并集,差集:(Set)
//book表存储book名称
set book:1:name    ”The Ruby Programming Language”
set book:2:name     ”Ruby on rail”
set book:3:name     ”Programming Erlang”

//tag表使用集合来存储数据,因为集合擅长求交集、并集
sadd tag:ruby 1
sadd tag:ruby 2
sadd tag:web 2
sadd tag:erlang 3

//即属于ruby又属于web的书?
 inter_list = redis.sinter("tag.web", "tag:ruby") 
//即属于ruby,但不属于web的书?
 inter_list = redis.sdiff("tag.ruby", "tag:web") 
//属于ruby和属于web的书的合集?
 inter_list = redis.sunion("tag.ruby", "tag:web")

面试题:

1、redis 的 zset 原理,使用场景,redis 线程模型,底层架构设计。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值