解决了redis的这些问题,你就是redis高手


解决了redis的这些问题,你就是redis高手

文章插图
 
什么是redis?Redis 本质上是一个 Key-Value 类型的内存数据库,整个数据库加载在内存当中进行操作,定期通过异步操作把数据库数据 flush 到硬盘上进行保存 。
因为是纯内存操作,Redis 的性能非常出色,每秒可以处理超过 10 万次读写操作,是已知性能
最快的 Key-Value DB 。
Redis 的出色之处不仅仅是性能,Redis 最大的魅力是支持保存多种数据结构,此外单个
value 的最大限制是 1GB,不像 memcached 只能保存 1MB 的数据,因此 Redis 可以用
来实现很多有用的功能,比方说用他的 List 来做 FIFO 双向链表,实现一个轻量级的高性 能
消息队列服务,用他的 Set 可以做高性能的 tag 系统等等 。
另外 Redis 也可以对存入的Key-Value 设置 expire 时间,因此也可以被当作一 个功能加强版的 memcached 来用 。
Redis 的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此 Redis 适合的场景主要局限在较小数据量的高性能操作和运算上
相比 memcached 有哪些优势?(1) memcached 所有的值均是简单的字符串,Redis 作为其替代者,支持更为丰富的数据类型
(2)Redis 的速度比 memcached 快很多
(3) Redis 可以持久化其数据
Redis 的全称是什么?Remote Dictionary Server 。
支持哪几种数据类型?String、 List、 Set、 Sorted Set、 hashes
Redis 有哪几种数据淘汰策略?
  1. noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但 DEL 和几个例外)
  2. allkeys-lru: 尝试回收最少使用的键(LRU),使得新添加的数据有空间存放 。
  3. volatile-lru: 尝试回收最少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存放 。
  4. allkeys-random: 回收随机的键使得新添加的数据有空间存放 。
  5. volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键 。
  6. volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL) 较短的键,使得新添加的数据有空间存放
redis为什么采用跳表而不是红黑树在做范围查找的时候,平衡树比skiplist操作要复杂 。在平衡树上,我们找到指定范围的小值之后,还需要以中序遍历的顺序继续寻找其它不超过大值的节点 。如果不对平衡树进行一定的改造,这里的中序遍历并不容易实现 。而在skiplist上进行范围查找就非常简单,只需要在找到小值之后,对第1层链表进行若干步的遍历就可以实现 。
平衡树的插入和删除操作可能引发子树的调整,逻辑复杂,而skiplist的插入和删除只需要修改相邻节点的指针,操作简单又快速 。
从内存占用上来说,skiplist比平衡树更灵活一些 。一般来说,平衡树每个节点包含2个指针(分别指向左右子树),而skiplist每个节点包含的指针数目平均为1/(1-p),具体取决于参数p的大小 。如果像Redis里的实现一样,取p=1/4,那么平均每个节点包含1.33个指针,比平衡树更有优势 。
查找单个key,skiplist和平衡树的时间复杂度都为O(log n),大体相当;而哈希表在保持较低的哈希值冲突概率的前提下,查找时间复杂度接近O(1),性能更高一些 。所以我们平常使用的各种Map或dictionary结构,大都是基于哈希表实现的 。
从算法实现难度上来比较,skiplist比平衡树要简单得多 。
介绍一下HyperLogLog?HyperLogLog 是一种概率数据结构,用来估算数据的基数 。数据集可以是网站访客的 IP 地址,E-mail 邮箱或者用户 ID 。
基数就是指一个集合中不同值的数目,比如 a, b, c, d 的基数就是 4,a, b, c, d, a 的基数还是 4 。虽然 a 出现两次,只会被计算一次 。
使用 Redis 统计集合的基数一般有三种方法,分别是使用 Redis 的 HashMap,BitMap 和 HyperLogLog 。前两个数据结构在集合的数量级增长时,所消耗的内存会大大增加,但是 HyperLogLog 则不会 。
Redis 的 HyperLogLog 通过牺牲准确率来减少内存空间的消耗,只需要12K内存,在标准误差0.81%的前提下,能够统计2^64个数据 。所以 HyperLogLog 是否适合在比如统计日活月活此类的对精度要不不高的场景 。
这是一个很惊人的结果,以如此小的内存来记录如此大数量级的数据基数 。
为什么 Redis 需要把所有数据放到内存中?Redis 为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘 。


推荐阅读