Spring in action 4 剑指Spring - (九)使用NoSQL数据库 - Redis

mac2025-10-07  7

使用NoSql数据库

NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。

NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。

Redis:

五大数据类型:

string 数据类型:

string 是Redis的最基本的数据类型,可以理解为与 Memcached 一模一样的类型,一个key 对应一个 value。string 类型是二进制安全的,意思是 Redis 的 string 可以包含任何数据,比如图片或者序列化的对象,一个 redis 中字符串 value 最多可以是 512M。

hash 数据类型:

hash 是一个键值对集合,是一个 string 类型的 key和 value 的映射表,key 还是key,但是value是一个键值对(key-value)。类比于 Java里面的 Map<String,Map<String,Object>> 集合。

list 数据类型:

list 列表,它是简单的字符串列表,按照插入顺序排序,你可以添加一个元素到列表的头部(左边)或者尾部(右边),它的底层实际上是个链表。

set 数据类型:

Redis 的 set 是 string 类型的无序集合。

zset 数据类型:

zset(sorted set 有序集合),和上面的set 数据类型一样,也是 string 类型元素的集合,但是它是有序的。

系统 相关命令:

key 相关命令:

关于 key 的命令应该说是最常用的,需要大家记住。

Redis持久化:

RDB方式 (默认) :

redis database 在指定时间间隔内,将内存中的数据作为一个快照文件(snapshot)写入到磁盘,读取的时候也是直接读取snapshot文件到内存。

自动触发:

redis.conf RDB配置:

# 时间策略 save 900 1 表示900 秒内如果至少有 1 个 key 的值变化,则保存 save 300 10 表示300 秒内如果至少有 10 个 key 的值变化,则保存 save 60 10000 表示60 秒内如果至少有 10000 个 key 的值变化,则保存 # 文件名称 dbfilename dump.rdb # 文件保存路径 dir /home/work/app/redis/data/ # 如果持久化出错,主进程是否停止写入 stop-writes-on-bgsave-error yes # 是否压缩 rdbcompression yes # 导入时是否检查 rdbchecksum yes

手动触发:

save 该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,知道RDB过程完成为止。 虽然该命令对于内存比较大的实例会造成长时间的阻塞,这是致命的缺陷,为了解决此问题,Redis提供了第二种方式。bgsave 执行该命令时,Redis会在后台异步进行快照操作,快照的同时还可以响应客户端请求。具体操作是Redis进程执行fork操作创建 子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。 基本上Redis内部所有的RDB操作都是采用bgsave命令。ps: 执行flushall命令,也会产生dump.rdb文件,但里面是空的,无意 义。

停止RDB持久化:

// 第一种方式 config set save "" // 第二种方式 redis-cli config set save ""

恢复数据:

// 查看备份文件 config get dir

将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可,redis就会自动加载文件数据至内存了。Redis 服务器在载入 RDB 文件期间,会一直处于阻塞状态,直到载入工作完成为止。

优势劣势:

优势 RDB是一个非常紧凑(compact)的文件,它保存了redis在某一个时间点上的数据集。这种文件非常适合用于进行备份和灾 难恢复生成RDB文件的时候,Redis主进程会fork()一个子进程来处理所有的保存工作,主进程不需要进行任何磁盘IO操作。RDB在恢复大数据集时的速度比AOF的恢复速度要快。 劣势 RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要执行fork操作创建子进程,属于重量级操作 (内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑),频繁执行成本过高(影响性能)。RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB 格式的问题(版本不兼容)。在一定间隔时间做一个备份,所以如果redis意外down掉的话,就会丢失最后一次快照的所有修改(数据有丢失).

AOF方式:

通过保存Redis服务器所执行的写命令来记录保存到AOF文件中。

redis.conf AOF配置:

# 是否开启aof appendonly yes # 文件名称 appendfilename "appendonly.aof" # 同步方式 appendfsync everysec # aof重写期间是否同步 no-appendfsync-on-rewrite no # 重写触发配置 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb # 加载aof时如果有错如何处理 aof-load-truncated yes # 文件重写策略 aof-rewrite-incremental-fsync yes appendonly: 默认值为no,也就是说redis默认使用的RDB方式持久化,如果需要开启AOF持久化方式,需要将appendonly修改为 yes。appendfilename:aof文件名,默认是appendonly.aofappendfsync: aof持久化策略的配置; no:表示不执行fsync,有操作系统保证数据同步到磁盘,速度最快,但是不太安全。always: 表示每次写入都执行fsync,以保证数据同步到磁盘,效率很低。everysec: 表示每一秒执行一次fsync,可能会导致丢失1s的数据。通常选择everysec,兼顾安全性和效率。 no-appendfsync-on-rewrite:默认值为no。 在AOF重写或者写入RDB文件的时候,会执行大量IO,此时执行everysec 和always的AOF模式来说,执行fsync会造成阻塞过长时间,no-appendfsync-on-rewrite字段设置为默认设置为no。如果对 延迟性要求很高的应用,这个字段可以设置为yes,否则还是设置为no,这样对持久化特性来说这是更加安全的选择。设置为yes 表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入。默认为no,建议yes。Linux的默认fsync策略是 30秒。可能丢失30秒数据。auto-aof-rewrite-percentage: 默认值为100。AOF自动重写配置,当目前AOF文件大小超过上一次重写AOF文件大小的 百分之多少进行重写,即当AOF文件增长到一定大小的时候,Redis能够调用bgrewriteaof对日志文件进行重写。当前AOF文件大 小是上一次日志重写得到AOF文件大小的二倍(设置为100)时,自动启动新的日志重写过程。auto-aof-rewrite-min-size: 64mb。设置允许重写的最小AOF文件大小,避免了达到约定的百分比但尺寸很小的情况还 要重写过程。aof-load-truncated: AOF文件可能在尾部是不完整的,当Redis启动的时候,AOF文件的数据被载入内存。重启可能发 生在redis所在的主机操作系统宕机后,尤其在ext4文件系统没有加上 data=ordered选项,出现这种情况。redis宕机或是异常 终止不会造成尾部不完整现象,可以选择让redis退出,或者导入尽可能多的数据。如果选择的是yes,当截断的AOF文件被导入 的时候,会自动发布一个log给客户端然后load。如果是no,用户必须手动redis-check-aof修复AOF文件才可以。默认为 yes。如果该配置启用,在加载时发现aof尾部不正确是,会向客户端写入一个log,但是会继续执行,如果设置为 no ,发现错误 就会停止,必须修复后才能重新加载。

开启AOF:

将 redis.conf 的 appendonly 配置改为 yes 即可。

# 是否开启aof 默认为no appendonly yes

AOF文件修复:

在使用的时候可能存在AOF文件出现错误的情况,比如:

*2 $3 del $1 a *3 $3 我是扰乱aof文件的字符 set $1 a $1 a -------------------开始修复redis-check-aof --fix appendonly1.aof----------------- ./redis-check-aof --fix appendonly1.aof 0x 46: Expected prefix '*', got: '▒' AOF analyzed: size=111, ok_up_to=70, diff=41 This will shrink the AOF from 111 bytes, with 41 bytes, to 70 bytes Continue? [y/N]: y Successfully truncated AOF -------------------修复过后----------------- *2 $6 SELECT $1 0 *3 $3 set $1 a $1 a *2 $3 del $1 a

命令:redis-check-aof --fix ‘aof_name’

优势劣势:

优点:  1、AOF 持久化的方法提供了多种的同步频率,即使使用默认的同步频率每秒同步一次,Redis 最多也就丢失 1 秒的数据而 已。  2、AOF 文件使用 Redis 命令追加的形式来构造,因此,即使 Redis 只能向 AOF 文件写入命令的片断,使用 redis-check- aof 工具也很容易修正 AOF 文件。  3、AOF 文件的格式可读性较强,这也为使用者提供了更灵活的处理方式。例如,如果我们不小心错用了 FLUSHALL 命令, 在重写还没进行时,我们可以手工将最后的 FLUSHALL 命令去掉,然后再使用 AOF 来恢复数据。

缺点:  1、对于具有相同数据的的 Redis,AOF 文件通常会比 RDB 文件体积更大。  2、虽然 AOF 提供了多种同步的频率,默认情况下,每秒同步一次的频率也具有较高的性能。但在 Redis 的负载较高时, RDB 比 AOF 具好更好的性能保证。  3、RDB 使用快照的形式来持久化整个 Redis 数据,而 AOF 只是将每次执行的命令追加到 AOF 文件中,因此从理论上说, RDB 比 AOF 方式更健壮。官方文档也指出,AOF 的确也存在一些 BUG,这些 BUG 在 RDB 没有存在。

那么对于 AOF 和 RDB 两种持久化方式,我们应该如何选择呢?  如果可以忍受一小段时间内数据的丢失,毫无疑问使用 RDB 是最好的,定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快,而且使用 RDB 还可以避免 AOF 一些隐藏的 bug; 否则就使用 AOF 重写。

但是一般情况下建议不要单独使用某一种持久化机制,而是应该两种一起用,在这种情况下,当redis重启的时候

会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。Redis后期 官方可能都有将两种持久化方式整合为一种持久化模型。

主从复制:

参考:

博客:https://www.cnblogs.com/ysocean/p/9143118.html#_label0

前面介绍Redis,我们都是在一台服务器上进行操作的,也就是说读和写以及备份操作都是在一台Redis服务器上进行的,那么随着项目访问量的增加,对Redis服务器的操作也越加频繁,虽然Redis读写速度都很快,但是一定程度上也会造成一定的延时,那么为了解决访问量大的问题,通常会采取的一种方式是主从架构Master/Slave,Master 以写为主,Slave 以读为主,Master 主节点更新后根据配置,自动同步到从机 Slave 节点。 接下来我们就来介绍如何进行主从架构的搭建。  ps:这里我是在一台机器上模拟多个Redis服务器,与实际生产环境中相比,基本配置都是一样,仅仅是IP地址和端口号变化。

修改配置文件Redis.conf:

修改 daemonize yes 表示修改Redis 以守护线程的方式启动(后台启动)。修改pidfile “/var/run/redis_6379.pid” 配置PID文件路径pidfile 表示当Redis作为守护线程运行的时候,它会把pid默认写到 /var/run/redis_6379.pid文件里面。修改port 6379 表示启动端口修改logfile “6379.log” 表示日志文件修改 dbfilename “dump_6379.rdb” 表示备份文件

以此配置6380的redis.conf , 6381的redis.conf。上面是以一个redis三个配置文件的方式,如果是复制三份redis,则有些配置可以不用修改。

启动Redis服务:

./redis-server redis1.conf ./redis-server redis2.conf ./redis-server redis3.conf

进入Redis客户端:

./redis-cli -p 6379 ./redis-cli -p 6380 ./redis-cli -p 6381

设置主从关系:

查看当前节点的角色信息:

info 或是 info replication ---------------------------- # Replication role:master connected_slaves:0 master_replid:edb3284fe387c2634d56365f349fdb282d077b95 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 此时"role:master"可以看到三个节点都是Master角色。如何将6380和6381节点变成Slave节点呢?

选择6380端口和6381端口,执行命令slaveof 127.0.0.1 6379

# Replication role:slave connected_slaves:0 master_replid:edb3284fe387c2634d56365f349fdb282d077b95 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 ------------------------------------------------------- role:slave 修改成功

这里通过命令来设置主从关系,一旦服务重启,那么角色关系将不复存在。想要永久的保存这种关系,可以通过配置redis.conf 文件来配置。

测试主从关系:

当在主节点执行set name 'cdd’命令后,从节点也可以get到。所以主从复制实现了。

全量复制 通过执行 slaveof 127.0.0.1 6379, 如果主节点6379以前还存在一些key-value。那么执行命令之后,从节点是否可以将主节点的旧信息复 制过来呢? 答案:肯定可以复制过来。

主从读写分离 主节点可以执行写命令,那么从节点是否可以执行写命令呢? 答案:从节点是不可以写入的,因为默认情况下,配置文件中配置了slave-read-only

slave-read-only yes

如果将其修改为no,从节点是可以写入数据的。

注意:即使将从节点的slave-read-only修改为no,从节点写入的数据,主节点还是复制不到的。

从节点宕机 主节点Master挂掉,两个从节点角色会变化吗? 答案:主节点 Master 挂掉之后,从节点角色还是不会改变的。

主节点宕机后恢复 主节点宕机之后,马上启动注解Master,主节点扮演的角色还是Master吗? 答案:主节点Master挂掉之后,重启后又恢复主节点的角色。

哨兵模式:

通过前面的配置,主节点Master 只有一个,一旦主节点挂掉之后,从节点没法担起主节点的任务,那么整个系统也无法运行。如果主节点挂 掉之后,从节点能够自动变成主节点,那么问题就解决了,于是哨兵模式诞生了。 哨兵模式就是不时地监控redis是否按照预期良好地运行(至少是保证主节点是存在的),若一台主机出现问题时,哨兵会自动将该主机下的某一个从机设置为新的主机,并让其他从机和新主机建立主从关系

哨兵模式搭建步骤:

配置在配置文件目录下的sentinel.conf,如果没有则新建,注意:名字一定不能写错。

sentinel monitor 被监控机器的名字(自己起名字) ip地址 端口号 得票数

sentinel monitor sentinel6379 127.0.0.1 6379 1 启动哨兵 使用./redis-sentinel ../sentinel.conf命令启动哨兵模式。

接下来,我们关闭主机6379,看节点之间的主从关系变化。 当我们把主节点6379关闭之后,此时由于开启了哨兵模式,不会像之前仅仅是主从复制那样。此时会根据投票方式 选出新的Master节点,此时6380节点为Master节点。

PS:哨兵模式也存在单点故障的问题,如果哨兵机器挂了,那么久无法进行了监控,解决办法就是哨兵也建立集群,Redis哨兵模式也支持集 群的。

主从复制的原理:

Redis的复制功能分为同步(sync)和命令传播(command propagate)两个操作。

旧版同步(旧数据同步) 当从节点发出 slaveof 命令,要求从服务器复制主服务器时,从服务器通过向主服务器发送 sync 命令来完成。该命令执行步骤:  1、从服务器向主服务器发送 sync 命令  2、收到 sync 命令的主服务器执行 bgsave 命令,在后台生成一个 RDB 文件,并使用一个缓冲区记录从开始执行的所有写命令  3、当主服务器的 bgsave 命令执行完毕时,主服务器会将 bgsave 命令生成的 RDB 文件发送给从服务器,从服务器接收此 RDB 文件 ,并将服务器状态更新为RDB文件记录的状态。  4、主服务器将缓冲区的所有写命令也发送给从服务器,从服务器执行相应命令。命令传播  当同步操作完成之后,主服务器会进行相应的修改命令,这时候从服务器和主服务器状态就会不一致。  为了让主服务器和从服务器保持状态一致,主服务器需要对从服务器执行命令传播操作,主服务器会将自己的写命令发送给从服务器执行。 从服务器执行相应的命令之后,主从服务器状态继续保持一致。  总结:通过同步操作以及命令传播功能,能够很好的保证了主从一致的特性。

但是我们考虑一个问题,如果从服务器在同步主服务器期间,突然断开了连接,而这时候主服务器进行了一些写操作,这时候从服务器恢复 连接,如果我们在进行同步,那么就必须将主服务器从新生成一个RDB文件,然后给从服务器加载,这样虽然能够保证一致性,但是其实断开连 接之前主从服务器状态是保持一致的,不一致的是从服务器断开连接,而主服务器执行了一些写命令,那么从服务器恢复连接后能不能只要断开 连接的哪些写命令,而不是整个RDB快照呢?  同步操作其实是一个非常耗时的操作,主服务器需要先通过bgsave 命令来生成一个 RDB 文件,然后需要将该文件发送给从服务器,从服 务器接收该文件之后,接着加载该文件,并且加载期间,从服务器是无法处理其他命令的。  为了解决这个问题,Redis从2.8版本之后,使用了新的同步命令 psync 来代替 sync 命令。该命令的部分重同步功能用于处理断线 后重复制的效率问题。也就是说当从服务器在断线后重新连接主服务器时,主服务器只将断开连接后执行的写命令发送给从服务器,从服务器只 需要接收并执行这些写命令即可保持主从一致。

主从复制的缺点:

主从复制虽然解决了主节点的单点故障问题,但是由于所有的写操作都是在 Master 节点上操作,然后同步到 Slave 节点,那么同步就会有一定的延时,当系统很繁忙的时候,延时问题就会更加严重,而且会随着从节点slave的增多而愈加严重

RedisTemplate:

pom.xml:

<!--redis--> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>2.1.9.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>

RedisConfig.java:

public class RedisConfig { /** * 直接new 一个对象返回,即默认它的各项属性(端口,主机名,密码等等)为默认值, * @return */ @Bean public JedisConnectionFactory jedisConnectionFactory(){ JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig()); jedisConnectionFactory.setUsePool(true); jedisConnectionFactory.setHostName("119.23.104.130"); jedisConnectionFactory.setPort(6379); return jedisConnectionFactory; } /** * jedis连接池配置,直接new 一个对象返回,使用默认值,如有需要可以为其各个属性配置值 * @return */ @Bean public JedisPoolConfig jedisPoolConfig(){ return new JedisPoolConfig(); } @Bean public RedisTemplate<Serializable, Serializable> redisTemplate(){ RedisTemplate<Serializable, Serializable> redisTemplate = new RedisTemplate<Serializable, Serializable>(); redisTemplate.setConnectionFactory(jedisConnectionFactory()); // 设置key的序列化器 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringRedisSerializer); // 设置values的序列化器 JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer(); redisTemplate.setValueSerializer(jdkSerializationRedisSerializer); return redisTemplate; } }

测试:

@RequestMapping("/Print9") @ResponseBody public Object Print9(){ redisTemplate.opsForValue().set("num","0"); Object a = redisTemplate.opsForValue().get("num"); return a; } @RequestMapping("/Print10") @ResponseBody public Object Print10(String key){ Object a = redisTemplate.opsForValue().get(key); return a; } @RequestMapping("/Print11") @ResponseBody public Object Print11(String key){ RedisUser cdd = new RedisUser("cdd", 23); redisTemplate.opsForValue().set("user",cdd); return "ok"; }

Redis连接工厂:

JedisConnectionFactory JredisConnectionFactory LettuceConnectionFactory SrpConnectionFactory

SpringDataRedis模板:

RedisTemplate StringRedisTemplate

序列化器:

GenericToStringSerializer:使用Spring转换服务进行序列化; JacksonJsonRedisSerializer:使用Jackson 1,将对象序列化为JSON; Jackson2JsonRedisSerializer:使用Jackson 2,将对象序列化为JSON; JdkSerializationRedisSerializer:使用Java序列化; OxmSerializer:使用Spring O/X映射的编排器和解排器(marshaler和unmarshaler)实现序列化,用于XML序列化; StringRedisSerializer:序列化String类型的key和value

Redis常见应用:

1、热点数据的缓存

由于redis访问速度块、支持的数据类型比较丰富,所以redis很适合用来存储热点数据,另外结合expire,我们可以设置过期时间然后再进行缓存更新操作,这个功能最为常见,我们几乎所有的项目都有所运用。

2、限时业务的运用

redis中可以使用expire命令设置一个键的生存时间,到时间后redis会删除它。利用这一特性可以运用在限时的优惠活动信息、手机验证码等业务场景。

3、计数器相关问题

redis由于incrby命令可以实现原子性的递增,所以可以运用于高并发的秒杀活动、分布式序列号的生成、具体业务还体现在比如限制一个手机号发多少条短信、一个接口一分钟限制多少请求、一个接口一天限制调用多少次等等。

4、排行榜相关问题

关系型数据库在排行榜方面查询速度普遍偏慢,所以可以借助redis的SortedSet进行热点数据的排序。

在奶茶活动中,我们需要展示各个部门的点赞排行榜, 所以我针对每个部门做了一个SortedSet,然后以用户的openid作为上面的username,以用户的点赞数作为上面的score, 然后针对每个用户做一个hash,通过zrangebyscore就可以按照点赞数获取排行榜,然后再根据username获取用户的hash信息,这个当时在实际运用中性能体验也蛮不错的。

5、分布式锁

这个主要利用redis的setnx命令进行,setnx:"set if not exists"就是如果不存在则成功设置缓存同时返回1,否则返回0 ,这个特性在俞你奔远方的后台中有所运用,因为我们服务器是集群的,定时任务可能在两台机器上都会运行,所以在定时任务中首先 通过setnx设置一个lock,如果成功设置则执行,如果没有成功设置,则表明该定时任务已执行。 当然结合具体业务,我们可以给这个lock加一个过期时间,比如说30分钟执行一次的定时任务,那么这个过期时间设置为小于30分钟的一个时间 就可以,这个与定时任务的周期以及定时任务执行消耗时间相关。

当然我们可以将这个特性运用于其他需要分布式锁的场景中,结合过期时间主要是防止死锁的出现。

6、延时操作

这个目前我做过相关测试,但是还没有运用到我们的实际项目中,下面我举个该特性的应用场景。 比如在订单生产后我们占用了库存,10分钟后去检验用户是够真正购买,如果没有购买将该单据设置无效,同时还原库存。 由于redis自2.8.0之后版本提供Keyspace Notifications功能,允许客户订阅Pub/Sub频道,以便以某种方式接收影响Redis数据集的事件。 所以我们对于上面的需求就可以用以下解决方案,我们在订单生产时,设置一个key,同时设置10分钟后过期, 我们在后台实现一个监听器,监听key的实效,监听到key失效时将后续逻辑加上。 当然我们也可以利用rabbitmq、activemq等消息中间件的延迟队列服务实现该需求。

7、分页、模糊搜索

redis的set集合中提供了一个zrangebylex方法,语法如下:

ZRANGEBYLEX key min max [LIMIT offset count]

通过ZRANGEBYLEX zset - + LIMIT 0 10 可以进行分页数据查询,其中- +表示获取全部数据

zrangebylex key min max 这个就可以返回字典区间的数据,利用这个特性可以进行模糊查询功能,这个也是目前我在redis中发现的唯一一个支持对存储内容进行模糊查询的特性。

前几天我通过这个特性,对学校数据进行了模拟测试,学校数据60万左右,响应时间在700ms左右,比mysql的like查询稍微快一点,但是由于它可以避免大量的数据库io操作,所以总体还是比直接mysql查询更利于系统的性能保障。

8、点赞、好友等相互关系的存储

Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。 又或者在微博应用中,每个用户关注的人存在一个集合中,就很容易实现求两个人的共同好友功能。

这个在奶茶活动中有运用,就是利用set存储用户之间的点赞关联的,另外在点赞前判断是否点赞过就利用了sismember方法,当时这个接口的响应时间控制在10毫秒内,十分高效。

9、队列

由于redis有list push和list pop这样的命令,所以能够很方便的执行队列操作。

最新回复(0)