关于redis的面试问题

1.redis的底层数据存储结构问题

 

   redis并不是简单的key-value数据容器,不能将其理解为静态存储数据,它是动态交互的数据结构服务器,可以被用作缓存,高性能k-v数据库等。

   它支持很多种类型的数据结构,不仅支持string类型的value,还支持很多种复杂类型的数据。以下简单列出redis支持的数据类型:

   1).安全二进制氏String类型:将String类型作为元素值;

 

问题:计数

一般情况都需要额外使用锁来避免并发写的问题。

解决方法:

 

使用incr命令来实现原子递增,使用get/set来重置计数状态。

与memcached相同,可作为key/value数据库,例如session共享。

   2).List类型:根据插入顺序的String类型为元素的集合,基于Linked List实现,非Array型;

 

利用pushpop操作可以实现消息队列,也可以实现关注列表、粉丝/在线好友列表等功能。

问题:显示最新的项目列表

SELECT * FROM foo WHERE ... ORDER BY TIME DESC LIMIT 10;

数据库上的查询语句如上,随着数据的增多,排序会越来越慢。
解决方法:

  • 为每一条数据选择一个唯一的ID(可选自增ID)
  • 缓存最新的N个数据,利用redis做数据缓存(list结构不断LPUSH最新的数据)
  • 当查询内容超过redis缓存内容后,才会穿透缓存访问数据库

消息队列的实现:

  • list数据结构作为channel
  • 生产者lpush消息
  • 消费者rpop消息
  • 设定超时时间

上述消息队列与PUB/SUB相比,不会丢失数据,但也没有失败重传的机制(也就是没有消息状态)

 

   3).Set类型:无重复且无序的String类型为元素的集合;

 

 

smembers可以用来实现好友列表中判断是否为已存在好友或关注好友,也可以通过集合操作来实现共同好友、共同兴趣、共同关注列表等。

问题:判断微博的共同好友、共同兴趣、是否为关注好友
解决方法:

  • 利用set集合存储用户的好友ID
  • 通过sismembers判断用户是否存在好友集合中
  • 通过sinter来判断两个好友集合的共同好友
  • 通过sunion来获取两个集合的所有好友
  • 通过sdiff来获取两个集合的非共同好友,用于好友推荐

 

   4).Sorted Set类型:无重复且有序的String类型为元素的集合;

 

 

score可以用来实现权重队列,也可以实现按时间、评分的自动排序列表。

问题:在线游戏实时排行榜
在线游戏的排行榜都需要实时更新操作,不可能去频繁地更改关系型数据库,
解决方法:

  • 为用户设置唯一的ID,采用sorted set来存储用户的得分情况
  • 利用有序集合来对用户得分进行排名,这里不可能存储全部的用户,可能只关心前100个用户,那么就需要在redis之外做限制

问题:新闻排序
新闻排序是按照新闻的关注度(点击率)和时间做排序,

score = points / (time^alpha)

上面的公式可以说明,点击率越高,越可能获得更多的评分;时间越久远,也会降低新闻的评分。因此,需要有一个专门用于计算新闻评分的进程,实时地处理最新的N条数据
解决方法:

  • 拉取最新的N条数据
  • 计算各个数据的评分
  • 添加到有序集合中

 

   5).Hash类型:映射域到值类型的数据结构,其中域和值都是String类型;

 

 

hash两种实现方式,

  • 当数据较少时,为了节省内存采用线性存储来节省空间
  • 当数据较多时,才会使用hashmap来降低时间复杂度

问题:商品维度计数
商品有各种计数(喜欢、评论、鉴定、浏览等)
解决方法:
使用hashfield字段来存储喜欢、评论等计数值。

同理,用户维度计数(动态、关注、粉丝、喜欢、发帖等)。

该存储结构适用于常用的商品、热门新闻动态等经常被大量访问的数据对象。

 

2.redis的add方法和set方法比较

 

       如果key已经存在,则调用Redis.Add(key, value)则不能添加或修改此key的内容value;这样的话,我们在添加一个key和value的时候,不得不判断一次ContainsKey(key),这样的话,就引起了两次搜索Reids的Hash Table的过程。 

   测试发现Redis的方法Set(key, value), 就相当于字典Dictionary.TryGetValue(key, out value)。完全实现了一次搜索,既可以新增数据 和 同时修改数据(如果之前key不存在)。

 

3.redis与memcached

  • redis支持更多的数据结构
  • memcached仅支持String类型的字符串
  • redis可以实现持久化存储,memcached不能实现

  • 底层的实现不同,与客户端的通信协议不同

redis支持两种存储方式:rdb-snapshot(快照)和aof(append only mode),rdb快照是定时将内存快照持久化到硬盘,但是有一个存储的时间间隔在这个间隔的过程中(crash会丢失数据),aof是在写入数据的同时将操作命令保存到日志(不会丢失数据,但操作日志管理维护成本高)

  • redis单线程,memcached是多线程的
  • redis修改libevent实现小巧的epoll,memcached完全依赖libevent(性能影响)
  • memcached使用CAS避免资源竞争修改,redis提供了事务功能

CAS是通过为每一个cacke key设置一个隐藏的cas token作为版本号,每次set操作都会检查并更新token

如有披露或问题欢迎留言或者入群探讨

关于redis的面试问题_第1张图片

 

 

 

你可能感兴趣的:(web核心,面试,redis,aof,rdb,结构)