一. 谈谈对 redis 的理解,它的应用场景。
Redis 是一个 key-value 存储系统,它支持存储的 value 类型包括 string 字符串、list 链表、set 集合、sorted Set 有序集合和 hash 哈希等数据类型。这些数据类型都支持 push/pop、add/remove 及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的,支持各种不同方式的排序。为了保证效率,Redis 将数据都缓存在内存中,并周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,在此基础上实现 master-slave(主从)同步。
Redis 的应用场景 数据类型应用场景 StringString 是最常用的一种数据类型,普通的 key/value 存储都可以归为此类。List 关注列表、粉丝列表、消息队列等。SetSet 提供一个与 List 类似的列表功能,特殊之处在于 Set 会自动排序、去重,当需要存储一个列表数据,又不希望有重复数据时,Set 是一个很好的选择,并且 set 提供了判断某个成员是否在一个 set 集合内的重要接口,这个也是 list 所不能提供的。
1. 使用 Set 存储一些集合性的数据,比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合;
2. 可以对集合取交集、并集、差集,应用到好友推荐、共同关注等。
3. 还可以利用唯一性,统计访问网站的所有独立 IP。
SortedSetSortedSet 与 Set 的使用场景类似,是不允许重复项的 String 集合。
1.SortedSet 可以通过提供一个优先级 (score) 的参数为成员排序,并且是插入有序的,即自动排序,可以应用于积分排行榜等。
2. 如果需要一个有序且不重复的集合列表,可以选择 sorted set 数据结构,比如 twitter 的 public timeline 可以以发表时间作为 score 来存储,这样获取时就是自动按时间排好序的。
3. 用 SortedSet 做带权重的队列,比如普通消息的 score 为 1,重要消息的 score 为 2,然后工作线程可以选择按 score 的倒序来获取工作任务,让重要的任务优先执行。
Hash 存储一个学生信息对象数据,字段包括:id、姓名、班级、年龄等,通过 id 可以获取 / 修改任意的字段。
二. 既然一般的语言也能支持 string、list、hash 等数据结构,为什么还要用 redis 呢?
这里要先提一下内存和缓存的区别:
内存是物理上的,是一种物理存储介质。
缓存是逻辑上的概念,是一种数据结构,可以是 PHP 语言里面的一种数据结构,也可以是 Redis 里面的一种数据结构。比如:用 PHP 数组存一些数据,每次有需求就直接从数组中读取;用 PHP 语言设计了一个缓存,用一个数组做队列,设计了一个基于先进先出策略的缓存;调用 Redis 的一些数据结构来存储数据。
内存叫做 RAM,随机可读存储器,硬盘一般叫做 ROM,随机只读存储器。
缓存包括 cpu 的一二级缓存、纯内存结构的缓存、半内存缓存、磁盘缓存,它们的速度是一层比一层慢。当 CPU 要读取一个数据时,首先从一级缓存中查找,如果没有找到再从二级缓存中查找,如果还是没有就从三级缓存或内存中查找,程序里面的各种数据结构、变量等等,都是运行在内存里面,而不是在硬盘上。
假设有一个场景,比如历史用户日志访问数据,就是 access_log,让你去统计都有哪些用户登录了这个网站,当然现在还有用户在持续登录着。这个时候你是不是要先去从 access_log 里面读取日志,然后提取出日志里面的 userId,存到数组里面再去重。当新用户来的时候,你只需要和你数组里面的用户进行比较即可,就不需要再读取 access_log 文件了。这样就不用每次读取文件,只需要读取数组即可,速度回更快。同理用 Redis,也是因为当我们需要读取数据时,先从 Redis 查找,如果有就直接返回,不用再从 mysql 查找,速度会很快。
从原理上讲,PHP 里面的数据结构用的是纯内存,而 Redis 是需要走网络的;
从速度上讲,纯内存的速度肯定是比先走网络、再从内存中读取的速度快。
虽然 Redis 作为半内存缓存,没有直接内存结构的数据结构速度快,但 Redis 除了数据结构丰富外,还适合高并发场景,对高并发处理效率极高,此外可以做到集群式、可持久化。
三. 具体讲一下 Redis 的数据结构,尽可能的举出他们的应用场景。
Redis 支持 String、List、Set、Sorted Set、Hash 等。
String 类型是二进制安全的,可以用来缓存一些静态文件,如图片、视频、css 文件等。支持 incr 操作,可以用作计数器,比如统计网站访问次数等。微博中“关注、粉丝”、论坛中所有回帖的 ID 用的就是 list 列表,还有消息队列,也是列表。Set 可以快速查找元素是否存在,用于记录一些不能重复的数据。例如:在网站注册账号时,用户名不能重复,使用 Set 记录注册用户,如果注册的用户名已经存在于 Set 中,就拒绝该用户注册。或者用于记录做过某些事情。例如:在某些投票系统中,每个用户一天只能投票一次,就可以用 Set 来记录某个用户的投票情况。Set 能做的事 Sorted Set 也能做,Sorted Set 还能完成一些 Set 不能做的事情。例如:使用 Sorted Set 构建一个具有优先级的队列。Hash 适用于存储对象,比如把用户的信息存到 hash 里,以用户 id 为 key,用户的详细信息为 value。