vlambda博客
学习文章列表

【绝杀面试官七问】Redis【进阶篇】(一)

 每天十分钟,轻松拿offer。






01

】Redis 中的管道有什么用?

一次请求/响应服务器能实现处理新的请求即使旧的请求还未被响应。这样就可以将多个命令发送到服务器,而不用等待回复,最后在一个步骤中读取该答复。这就是管道(pipelining),是一种几十年来广泛使用的技术。例如许多POP3协议已经实现支持这个功能,大大加快了从服务器下载新邮件的过程。




02

】怎么理解 Redis 事务?

  • 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

  • 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

  • redis事务 没有隔离级别




03

】Redis 事务相关的命令有哪几个?

MULTI    EXEC    DISCARD    WATCH

ps:

  • MULTI命令

用于开启一个事务,它总是返回OK。MULTI执行之后,客户端可以继续向服务器发送任意多条命令, 这些命令不会立即被执行,而是被放到一个队列中,当 EXEC命令被调用时, 所有队列中的命令才会被执行。

  • EXEC命令

负责触发并执行事务中的所有命令:

如果客户端成功开启事务后执行EXEC,那么事务中的所有命令都会被执行。

如果客户端在使用MULTI开启了事务后,却因为断线而没有成功执行EXEC,那么事务中的所有命令都不会被执行。

需要特别注意的是:即使事务中有某条/某些命令执行失败了,事务队列中的其他命令仍然会继续执行——Redis不会停止执行事务中的命令,而不会像我们通常使用的关系型数据库一样进行回滚。

  • DISCARD命令

当执行 DISCARD 命令时, 事务会被放弃, 事务队列会被清空,并且客户端会从事务状态中退出。

  • WATCH 命令

可以为Redis事务提供 check-and-set (CAS)行为。被WATCH的键会被监视,并会发觉这些键是否被改动过了。如果有至少一个被监视的键在 EXEC 执行之前被修改了, 那么整个事务都会被取消, EXEC 返回nil-reply来表示事务已经失败。




04

】Redis key 的过期时间和永久有效分别怎么设置?

  • 通过expire设置过期时间  

  •     例如:expire key 100 (key在100秒后过期)

  • 通过persist对key进行持久化

    • 例如:persist key(清楚key的过期时间)




05

】Redis 如何做内存优化?

1、缩减键值对象

    缩减键(key)和值(value)的长度。

    key长度:如在设计键时,在完整描述业务情况下,键值越短越好。

    value长度:值对象缩减比较复杂,常见需求是把业务对象序列化成二进制数组放入Redis。首先应该在业务上精简业务对象,去掉不必要的属性避免存储无效数据。其次在序列化工具选择上,应该选择更高效的序列化工具来降低字节数组大小。以JAVA为例,内置的序列化方式无论从速度还是压缩比都不尽如人意,这时可以选择更高效的序列化工具,如: protostuff,kryo等

2、共享对象池

  对象共享池指Redis内部维护[0-9999]的整数对象池。创建大量的整数类型redisObject存在内存开销,每个redisObject内部结构至少占16字节,甚至超过了整数自身空间消耗。所以Redis内存维护一个[0-9999]的整数对象池,用于节约内存。除了整数值对象,其他类型如list,hash,set,zset内部元素也可以使用整数对象池。因此开发中在满足需求的前提下,尽量使用整数对象以节省内存。

3、字符串优化

4、编码优化

5、控制key的数量




06

】Redis 回收进程如何工作的?

一个客户端运行了新的命令,添加了新的数据。Redi检查内存使用情况,如果大于maxmemory的限制, 则根据设定好的策略进行回收。一个新的命令被执行,等等。

ps:我们不断地穿越内存限制的边界,通过不断达到边界然后不断地回收回到边界以下。如果一个命令的结果导致大量内存被使用(例如很大的集合的交集保存到一个新的键),不用多久内存限制就会被这个内存使用量超越。




07

】Redis 加锁机制?

在事务中,可以通过watch命令来加锁;使用 UNWATCH 可以取消加锁;

如果在事务之前,执行了WATCH(加锁),那么执行 EXEC 命令或 DISCARD 命令后,锁对自动释放,即不需要再执行 UNWATCH 了。Redis采用了乐观锁策略(通过watch操作)。

ps:Redis只支持乐观锁!

        乐观锁支持读操作,适用于多读少写的情况!