https://www.zhihu.com/question/20734566
https://www.zhihu.com/question/19660689
http://blog.csdn.net/Ideality_hunter/article/details/77621643
redis和mysql要根据具体业务场景去选型
- mysql:数据放在磁盘
- redis:数据放在内存
redis适合放一些频繁使用,比较热的数据,因为是放在内存中,读写速度都非常快,一般会应用在下面一些场景
-
- 排行榜
- 计数器
- 消息队列推送
- 好友关注,粉丝
首先要知道mysql存储在磁盘里,redis存储在内存里,redis既可以用来做持久存储,也可以做缓存,而目前大多数公司的存储都是mysql + redis,mysql作为主存储,redis作为辅助存储被用作缓存,加快访问读取的速度,提高性能
那么为什么不直接全部用redis存储呢?
我的看法是:因为redis存储在内存中,如果存储在内存中,存储容量肯定要比磁盘少很多,那么要存储大量数据,只能花更多的钱去购买内存,造成在一些不需要高性能的地方是相对比较浪费的,所以目前基本都是mysql(主) + redis(辅),在需要性能的地方使用redis,在不需要高性能的地方使用mysql,好钢用在刀刃上
目前redis做数据库还不太靠谱。它支持的数据类型太少,而且查询功能太弱。redis并不是为了作为数据库使用的,它更多地是一个高速存取器,一般用作缓存和类似场景。
如果你想找一个关系型数据库如mysql的替代者,推荐使用mongodb,支持海量数据,查询功能强大,数据类型支持广泛。目前已有一些团队在后台完全使用mongodb作为数据库。
单独使用Redis的话,它是成当不起数据库的任务,比如你每日活跃用户是1万人,但是你那台redis里面已经积累了50万人了(这个比例很正常),那么每次redis启动,就需要把50万load内存,每次redis备份,又需要把50万dump到磁盘,这靠谱么?
======================
补充1:可以用SSDB代替(redis协议+leveldb存储),生产环节若干 PCU百万级项目用过。
补充2:看了下陌陌争霸的方案,旁路存储,如果觉得时间充足,也可以仿照实现。
补充3:把冷数据落地到mongo,热数据在用redis存储。
使用redis作为缓存,数据还需要存入数据库中吗?
我的答案是:
1redis只是缓存,不是数据库如mysql,所以redis中有的数据库,mysql中一定有。
2用户请求先去请求redis,如果没有,再去数据库中去读取。
3redis中缓存一些请求量比较大的数据(这些缓存数据,mysql中一定也是有的),没必要所有数据都缓存到redis中。
5之所以从缓存中拿数据会快,是因为缓存的数据存在于内存中,不像mysql的数据是存在磁盘上的,即不用经过从磁盘加载到内存这个过程(这个过程是非常耗时和低效的),直接从内存获取数据。
6当redis缓存崩溃的时候,那么不是海量的请求都去访问数据库了?数据库能抗住吗?
1)收下要分析,当成千亿个请求同时访问过来,数据库为什么会扛不住?
①超大量的并发,数据库扛不住。
举个例子就明白了。
10000万个plsql客户端,同时访问Oracle进行数据库查询、写入等操作,数据库肯定吃不消。
参考:http://blog.csdn.net/ideality_hunter/article/details/77621802
从这个角度来说,redis并不能帮什么忙。
②数据库存在低速设备上,每次访问数据库,都要经过io,即从磁盘调入内存的过程。这个才是使用redis等缓存机制的原因。
2)当redis奔溃了,成千亿个请求同时访问过来,数据库扛不住,该怎么办?
=====解答某些同学的提问,核心是,redis中存的数据,数据库中是否还要存的问题。
我的观点:
1前提:mysql中存all即所有的数据(redis只是缓存的mysql中的部分数据),redis中缓存mysql中存在的访问量超级大的数据。
2如果redis中没有我要的数据,那么其实这些请求并发量没有那么大(为什么?参看上面的前提),那么就去mysql访问,肯定并没有太大压力。
反方观点1:既然redis中存了,数据库为什么还要存呢?所以他们认为数据存入redis就不用存数据库了。
反方观点2:如果redis崩溃了,缓存丢失了,不是所有的请求都压到mysql了?mysql数据是存在硬盘上的,读取是低速的,mysql肯定扛不住。
我的解答:
解答反方观点1:这个不用争,redis是当缓存用的,不是当数据库用的。
解答反方观点2:我承认mysql这种情况下肯定扛不住,但是你全把数据放入redis风险不就更大了吗?因为我虽然慢,但是最起码没有丢失,但是你redis是放入内存的,所有数据都丢失了?
反方观点3:我的redis数据并没有丢啊,redis有灾备机制,因为redis会将其中的数据实时地存入磁盘,这样就不怕丢了。
解答反方观点3:那这不是回到我的思路上了吗?你存磁盘其实跟存数据库不是一个道理吗?方正都是存磁盘?你怎么能将99G或者更大的数据快速的从磁盘加载到redis即内存中呢?不可能的。
所以,咱们两种方式其实都是一样的,都解决不了,如果redis即内存崩溃了,然后重启redis之后,怎么快速的响应千万甚至过亿的请求。
我的方式:redis坏了,从数据库读取。
你的方式:redis坏了,从磁盘慢慢地恢复到redis,然后从redis读取。
反方观点5:如果redis崩溃了,我不光可以放入磁盘一种方式,我还可以放入所在集群中的其他机器如B的内存中啊,这样如果机器A的redis崩溃了,只需要去访问机器B的内存中去取所需要的内容即可。
解答反方观点5:①这种方式我没研究过,集群,竟然内存也是共享的?②就算你说的是对的,我的那种方式,也完全可以融入你的机制,如果redis崩溃了,也将数据转移到集群中的B的内存中。这样的话,咱俩的方式其实就一样了。
反方观点6:你如果也采取我的那种方式,将数据转移到集群中的其他机器的内存中,那么为什么还要再存入mysql中一份呢,完全没有必要,因为对于这部分数据,根本不会去mysql中去读取的,一直是在redis中读取就行了。
解答反方观点6:你是对的,我无言以对。但是我质疑你说的将数据转移到集群中其他机器上这种方式的可行性。
我对反方观点5的质疑:照你你这种机制,其实就可以不用硬盘了,你用内存就行了,你可以把所有的数据都存入redis了,还将用户等信息放入mysql中干什么?
反方解答我的质疑:mysql中存的是不经常访问的事情。
总结:
的确, 如果可以实现A机器崩溃时可以将redis中的数据转移到集群中机器B的内存中(我对这种方式的可行性是质疑的),那么,数据存入redis就可以不用存入mysql,但是这就颠覆了我及常人对缓存的理解,这其实就不是什么缓存,而是直接将redis当数据库来用了。
竟然还真有这种方式:
https://www.zhihu.com/question/21419897