前言本文不是具体的教程,阿芬打算记录下自己对Redis的一些感悟。说来惭愧,阿芬刚开始接触Redis的时候,也只是简单的用了一下,背了一些面试题,把Redis的技能点写在了简历上。我们很容易在网上找到关于Redis具体知识点的解释,但是很少有文字解释为什么会有这种技术存在。阿芬希望通过这篇文章总结一下我目前对Redis的理解。1、刚开始接触Redis的时候,阿芬是通过网上的一些项目教程来了解Redis的。当时教程说把首页数据放到Redis中可以加快首页数据的访问速度。我做到了。代码运行后,发现好像加载的挺快的,算是完成了。项目做完后,我在简历里写了,顺便在技能里写上我熟练使用Redis,然后背了几道关于Redis数据类型和持久化机制的面试题,然后就去了找实习。面试的时候,面试官问阿芬:你为什么用Redis?阿芬按照项目教程重复了一遍:因为可以让首页加载数据更快,所以我们的产品首页很重要,加载数据越快,用户越满意。。。现在回想起来,我真是哭笑不得,也不能说这个回答有问题。Redis作为缓存的一大亮点就是可以加快数据查询效率,但是如果从技术面试的角度来看,这个答案其实应该是从技术角度来回答的,这也是其中之一促使阿芬写这篇文章的冲动。2、为什么要有Redis技术?(你为什么用Redis)如果问你现在为什么用Redis,阿芬打算从计算机的存储结构说起。计算机界有一本名著《深入理解计算机系统》,里面有一张很经典的关于计算机存储结构的图:从图中可以看出,计算机内存是一个金字塔结构,内存存储效率越高,越低存储效率越低。计算机中的内存层位于磁盘之上,内存的存储效率比磁盘快很多。一般情况下,我们会将应用数据存储在数据库中,数据库将数据存储在磁盘上;而Redis是一个基于内存的存储系统,数据是存储在内存中的,也就是说从Redis中读取数据比从数据库中读取数据要快。更快获取数据的根本原因。看到这里,你可能会说,数据存储在内存中有什么了不起的?我可以使用谷歌的番石榴!再不济,我直接新建一个HashMap来存数据就可以了。这不都是靠记忆吗?这个问题让我想起了在网上看facebook时看到的一个问题:如果让你设计缓存,你会怎么设计?大家可以想一想guava和Map集合的不足之处是什么?很明显,这是虽然两者都是基于内存的,但是他们使用的是jvm的内存。如果jvm挂了或者重启了,数据就会丢失。这就很容易让我们想到Redis的持久化机制。Redis的持久化机制使得内存中的数据能够持久化到磁盘中,解决了内存数据掉电后易挥发的问题。而且Redis是jvm中不需要依赖的中间件。(一开始只是背Redis的持久化机制,并没有思考为什么,想搞清楚背后的关系再去学,才能学的更扎实。)另一个角度:既然数据库是因为磁盘慢,为什么不在内存中实现数据库呢?还别说,SAP还真有基于内存的数据库系统,但是使用内存有个致命的缺点:贵!能买得起那套软件和庞大的内存机器公司毕竟是少数,所以之所以用Redis,是因为它在低效的磁盘和昂贵的内存之间做出了妥协。补充:面试的时候被问到一个问题:Redis的内存淘汰机制当时直接被搞糊涂了,后来想了想,这其实是一个很正常的考点:Redis在内存中存储数据,内存空间是有限的.总会有用完的一天。当内存用完后,必须有相应的内存淘汰策略来释放内存。但是说到记忆消除,我又想到了一个进阶的知识点。由于Redis的内存是有限的,所以我们在使用内存的时候要更加小心。在Redis中有很多方法可以有效地使用内存。比如我们在存储用户信息的时候,将用户信息存储为hash,比用key-value逐条存储用户信息占用的空间要小得多。这些知识你可以在Redid的官方网站上找到。3、关于Redis的主从复制、哨兵、集群在学习Redis之前,我对分布式知识知之甚少。当时,当我背面试Redis的面试题,背主从复制、哨兵、集群等知识点的时候,既兴奋又不知所措。背了之后感觉自己掌握了很多分布式的知识,但是把这些知识点都揉在一起了,完全不知道背后的逻辑是什么。既然想通了,还是记下来吧:在扩展到多机之前,先想一想单机Redis的缺点:可能存在单点故障,导致Redis服务不可用。单机内存有限。不能存储太多数据。如果访问量大,单机压力会很大。通过第一个缺点,我们可以引出为什么需要主从复制和哨兵。大家想一想,如果我们只有一个Redis服务,服务挂了就不能用了,但是如果再安排一个Redis服务器,它的数据会一直和第一个Redis的数据保持一致,这样当首先在第一个Redis挂掉后,我们可以将请求迁移到第二个Redis,这样就提高了Redis服务的可用性。为了让第二台Redis的数据和第一台Redis保持一致,我们需要使用主从复制。有时,一主一从的配置可能不够安全。这时候,我们需要配置两个或多个从节点作为主节点。那么问题来了。如果主节点挂了,我们应该用什么方案把主节点安装到从节点上呢?选举一个新的主节点怎么样?这使用哨兵机制。并且在一主多从的情况下,我们使用主从复制来保持多个Redis的数据一致。这时候我们可以把读请求分发给从节点,这样可以有效的缓解主节点的读压力。但是,如果Redis的写请求压力也很大,而且数据量很大,这个时候再给Redis增加一台备份机来横向扩展就没有多大用处了。这时候就要考虑纵向扩展,增加多个Redis共享写入。请求让不同的密钥落在不同的机器上。这时候,我们不得不考虑使用一致性哈希等算法,将不同的密钥分配给不同的机器。Redis本身也提供了集群机制,但是内部使用的不是一致性哈希,而是哈希槽。简单来说就是在hashslot中划分不同的区间,不同的区间对应不同的机制;在扩容或缩容时,都有相应的哈希槽调整策略。刚开始学习Redis的多机策略时,一直搞不清楚集群、主从复制、哨兵机制之间的关系。集群其实就是一个完整的Redis多机解决方案,有效的解决了单机Redis的所有问题。当您为集群中的节点配置从机时,主从节点同步使用主从复制。主节点挂掉后,选择从节点的内部逻辑类似于哨兵机制。当我们使用集群机制时,我们可以省去编写一致性哈希等分配逻辑的需要。集群机制会在节点上添加相应的数据结构来完成这些功能。如果想了解集群背后的实现原理,我推荐这样的学习路线:先登录官网,按照官网的步骤学习配置主从复制,配置哨兵,搭建集群,然后看完了《Redis的设计与实现》这本书,看了master-slavereplication,Sentinel和Cluster4这三章。后来阿芬觉得如果对文中提到的Redis的几点有深刻的理解,Redis基本可以视为介绍。写这篇思考的主要目的是提醒自己,学习一门技术要问为什么,这样知识学了就不容易忘记。至于为什么只能说是入门级的Redis,因为Redis的用法太多了,你可以把它当缓存用,也可以当数据库用,甚至可以当消息队列用.大家可能对缓存不陌生。Redis在数据库方面有着无限的潜力。你一定要用好它的bitmap位图功能,面对复杂的需求时可以用到。比如老板要统计一年所有用户登录天数,一个用户只需要365bit(46B)的空间,比起使用传统的mysql不知道节省了多少倍的空间。阿芬觉得,如果自己能够将一项技术实力运用到自己的系统中,也算是用好了这项技术。关于Redis,在实际应用中还有很多值得我们自己去探索的地方,大家一起共勉吧!
