nosql中leader选举算法法有哪些功能是什么?

  • [微综述] 搜索专家 @孙明明_SmarterChina 在"知识图谱与搜索引擎"中推荐了建立知识图谱和利用知识图谱的12篇重要文献,涵盖利用百科数据,挖掘生成知识图谱,搜索引擎页面排序,利用实体标注、语义匹配,查询中的实体映射等前沿话题。导读 文献列表 [ ]

  • 产品设计的死循环(参见高尔定律第二原则)。附:高尔定律(Gall's law) 1、成功复杂系统是从已经成功的简单系统演进而来;2、凭空设计出来的复杂系统不会成功、再怎么打补丁也不行,只能推倒重来;3,简单系统未必成功。 [ ]

  • Sibyl是Google正在使用的分布式机器学习平台。它于2010年在大规模分布系统论坛(LADIS)就做过主题报告,今年又到DSN做了一次主题报告(视频林大原则讲得很清楚)。到底这四年有什么变化,看看下图(含四个关键幻灯片)就明白了。相关资料合集传送门: [ ]

  • @理想主义de患者 问:有没有垃圾邮件检测的项目啊。答:比较有效的方法都是结合机器学习与人工知识的。最有名的开源项目是SpamAssassin,可以从很多语言调用如Python 。另有个开源项目Stopspam也值得关注。更早基于机器学习的项目合集中也有个列表 [ ] [

  • @羊_o羊o羊爱小破厂 问:需要tornado的资料。答:Tornado是一个非阻塞式Python网络框架,并发性能优于大多数其他Python框架。这组资料是基本介绍,中英文都有

  • @钱知易 问有没有机器学习和深度学习在多媒体信息检索领域的资源?答:机器学习应用太广,本条只涉及深度学习。其中图像检索@姚鹏鹏YPP 已问过,见答案 语音检索,Google语音组和微软邓力等是领先的,他们主页上的文章基本代表了前沿,一些教程在此 [ ] [ ]

  • 世界级专家精选讲义第一组,今天推出RPI的James Hendler (维基百科介绍 )研究领域人工智能和Web科学,前IEEE

  • 上列一批计算机高质量书籍,可惜很多链接都失效了。当时承诺帮大家找到可下载的版本,今天终于有空先找了第一批“特别推荐系列”里的7篇,提供了免登录下载。原作者有@52nlp @朱鉴 @陈涛sean @rickjin 非常非常感谢他们! (更多待续) [ ]

  • 去年2月Nature指出Google在流感预测上出现重大错误:过高估计发病几率。今年3月Science讲了两个原因:抛弃传统方法过度依赖大数据,算法难以有效过滤网络舆情。前段时间纽约时报也讨论了大数据的局限。这里我们汇总了6篇相关文章,从正反两方面提供参考 感谢 @lidingpku 提供 [ ]

  • @tang_Kaka_back 问:有没有时间序列分析的相关资料?答:这里收集了一组时间序列分析入门资源。分为三组:第一组是三本电子书,都是经典,其中两本免费 第二组是9个教程,来自博客和中外大学课件 第三组是维基百科上的核心概念介绍 [

  • 第二组教程里有两个PPT 一个讲理论一个讲实战。在几篇博客里,特别推荐@敲代码的张洋 的 “时间序列分析基础” 基本概念,ARIMA/Ar/MA模型,R的实现都有,非常适合入门 [ ]
  • 第三组基本概念,也推荐看这个博客上的图 , 简明扼要,要搞懂什么概念一目了然。基础概念有时域分析,频域分析,ARIMA模型和各种变种。英文维基介绍的很清楚 [ ]
  • 续时间序列分析入门24个资源 再推荐更多进阶内容。Memect大数据精华区有很多Hadoop上的时间序列分析文章 Python精华区有统计实战和StatsModels等包的介绍 最后推荐一个统计专家的专辑,有很多有趣的统计文章 [完] [ ]
  • Shadbolt (英国政府公开数据领导者),Jim Hendler(语义网之父)等主讲。内容涉及链接数据,开放数据,数据分析等。共41个资源 感谢@lidingpku 推荐 [ ]

  • @呯呀么呯 问:识别交通标志,怎么确定图片里有交通标志,具体在哪里?答:这个应该算目标识别和物体识别,CV的经典教程都有object recognition的内容可以参考。具体到交通标志识别,Github上有些开源代码 Matlab C++ Java的都有 计算机视觉@DeepGlint赵勇 是专家,推荐关注 [ ] [ ]

  • 问:@北冥渔翁:日常维护管理的有吗?dba方面? 答:oracle dba在学习官方文档外,可以跟踪大神的博客,篇幅都不长且能很快掌握很多有用的实战经验。此外面试问题也反映了dba的技术要点。合集传送门 推荐资深dba微博 @yangtingkun 有很多好文摘 [ ] [ ]

    • @老熊的三分地 (Jun Xiong) 也是Oracle DBA的资深专家,特别推荐他的同名的中文博客 上的教程和源代码。Python实现,是基于pylearn2和Theano的。目前500多星,非常火爆。他们的wiki上很不错的资源列表,如论文和数据集 [ ]
    • 14)OpenDL 这是个很新的实现, 是基于spark的。语言是Java。除了spark还用到了Mallet机器学习包和JBlas线性代数包。更多spark参考请看大数据精华区的专题 。 [ ]
  • 16) @丕子 的PG_DEEP 这是一个C++实现的Demo,目前有20星。代码相对简单,非常适合入门学习。 [ ]
  • 问:@apple2811 我需要Linux的资料 答:不太清楚具体需要哪一类,先推荐些通用的:1)六篇入门导读,包括Linux的基本知识,学习Linux的攻略,以及在线学习资源列表 2) 六个社区网站(中英文各半),包括官方网站,流量最大的社区,以及问答论坛 [ ] [ ]

  • 问:@如果起居录 语义网用于GIS、RS领域 答:OGC在2000年制定 此外@朝花夕拾录 还介绍过emcee和pystan。在实战中怎么用呢?bayesian-python这个系列收集了14篇相关文章。 这5篇总结了几个工具的实战例程。要节约时间就看系列第一篇总结的表,一目了然 [ ]

  • @西瓜大丸子汤 刚才说到python优化,举个具体的例子 Gensim的作者把word2vec(深度学习)做了几个经典优化:循环,numpy/BLAS,cython,多线程(真的可以)结果效率提高了上千倍,比Google开源出来的原始C版本还快3倍。他最近还写了个word2vec教程。无论是学习word2vec还是python优化,都不可不看

  • @朝花夕拾录 白宫和麻省理工于今年三月举办了“大数据的个人隐私研讨会”。麻省理工校长主持,白宫大数据顾问、美国商业部部长作了主题演讲,还有一堆麻省理工和哈佛的教授研讨了关键技术,包括数据库,加密,匿名,日志分析,语义推理等。相关资源包括每个演讲的视频,以及八个可下载的PPT。 [ ] ** 刚刚整理出了4个大数据信息安全关键问题: *数据收集,如何签订合理的用户知情协议 *数据共享,如何保障透明度,控制使用权限,防止数据泄露 *数据使用,如何避免重新识别攻击,防止意外地侵犯个人权益 *数据监管:如何在不同的环境(国家、政府、组织、政策)中监管大数据的运营 [ ]

  • (well,其实lua,不过从ipython调用很容易),基本常用的通用python机器学习平台都有了。 [ ]

  • ,大数定律,金融分析等概念与应用。Github上已经有5000颗星。更多python统计方法资源 [ ]

  • @朝花夕拾录 #大数据#产业化的一个重要指标:超过20家美国商学院(例如UVA,RPI,GWU)开设了大数据和数据分析硕士课程,而且有一半学校的课程只要一年就能毕业。这个可是转型成高富帅的绝佳机会呦。 --我是分割线-- 呵呵,还有个IIT,这可不是印度学校,是伊利诺伊理工大学。 [ ]

  • @西瓜大丸子汤 Spark Summit 2013的PPT和教程合集整理在此 ,一共33个。和昨天放出了60个Spark Summit 2014的PPT一起,基本涵盖了近期spark的动态与产业布局。 和去年比,今年峰会的内容无论数量还是应用的广度与深度,都大幅增长了。例如去年没有自然语言处理,今年有两个 [

  • *Frequentists的长远目标是只有5%的时间犯错误 *Bayesians隐约期待马,瞥见一头驴,坚信(95%的可能性)他看到了一头骡子 [ ]

  • @developerWorks 免费电子书《面向程序员的数据挖掘实战指南》,侧重实例,以 Python 语言讲解。目前已完成6章,仍在更新中,并且提供 PDF 下载。 作者:Ron Zacharski cc

  • @陈利人 【机器学习中的数学系列】回归、梯度下降 ;线性回归,偏差、方差权衡 ;强大的矩阵奇异值分解及其应用 [ ]

@好东西传送门 是开源的,任何人都可以贡献好的文献、代码或商业产品。你可以fork一份github库,并在awesome目录下建立一个文件,内容就是链接(文字描述可选)例 提交一个pull请求,剩下的就交给传送门了。您的贡献会被署名 [ [微博]() ] @好东西传送门 开源5天,已经有了88颗星。这里解释一下开源政策:为了鼓励好东西的传播,我们采用了Creative Commons Attribution-NonCommercial-ShareAlike 4.0许可证:Github上的内容可以被自由分享和改编,但需用同样的许可证发布,致谢@好东西传送门 并不得用于商用 [ [微博]() ]
  • 开源的好东西传送门:今天我们已经把所有的问答和文摘都整理到Github上了,查看别人已经问过的问题更加容易。你可以一键复制,拥有自己不会丢失的好东西列表。也可以关注项目获得更新通知。如果你关心大数据、机器学习、数据库、Web、Python(话题增长中)去加星收藏吧 [ ]

  • 这样认领问题:去Github Issue列表下面 找一个感兴趣的问题,回复你想分享的资源链接,也可附简单评语。请留下你的微博帐号(或其他联系方式),好东西传送门会整理后贴出你的答案并注明贡献者是你 [ ]

  • 传送门也有微信了,去扫描吧。或者按名字直接加“好东西传送门”。微信会更多承载每日精华整理的功能。如果错过了微博上的好东西,微信上还会看到。转发一下,让更多人看到最精彩的技术好东西! [ ]

  • 好东西传送门所有问答和推荐资源合集现在都放在Github上了!每个问题都有自己的讨论页,可讨论增补。目前还有十多条未完成问题,欢迎各位专家帮忙认领回答!8月5日前转发最多的两条答案将获赠 @TechCrunch中国 国际创新北京峰会双日VIP票,本来3200一张哦! [ ]

  • 回复@silverhawk_ny:轻问答就是相对知乎这样的“重”问答工具而言,利用机器生成大量的知识卡片,问答时回答问题的人只要利用自己的知识,快速组织卡片。一般这个过程不需要写长文,几分钟就可以完成,所以叫“轻”//@silverhawk_ny:轻问答是什么意思? [ ]

  • 《好东西传送门到底是什么?》 很多人问这个帐号到底是什么?答:它是一个网上资料的人肉搜索引擎。它集成了一群微博上的好人,以最简练的方式,帮大家找到最精华的资源。达到这个目的手段有三:知识卡片,人肉知识桥梁,轻问答。这是不是你想要的“好东西传送门”?欢迎讨论! [ ]

nosql,泛指非关系型的。随着互联网不断的发展,传统的关系数据库在应付新互联网模式的网站,特别是超大规模和高并发的sns类型的纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。nosql数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。而今天主要讲用得比较多的三个nosql:memcached、redis、mongodb。

1.memcached可以利用多核优势,单实例吞吐量极高,可以达到几十万qps(取决于key、value的字节大小以及服务器硬件性能,日常环境中qps高峰大约在4-6w左右)。适用于最大程度扛量。

1.只支持简单的key/value数据结构,不像redis可以支持丰富的数据类型。

2.无法进行持久化,数据不能备份,只能用于缓存使用,且重启后数据全部丢失。

3.无法进行数据同步,不能将mc中的数据迁移到其他mc实例中。

4.memcached内存分配采用slab allocation机制管理内存,value大小分布差异较大时会造成内存利用率降低,并引发低利用率时依然出现踢出等问题。需要用户注重value设计。

2.支持持久化操作,可以进行aof及rdb数据持久化到磁盘,从而进行数据备份或数据恢复等操作,较好的防止数据丢失的手段。

3.支持通过replication进行数据复制,通过master-slave机制,可以实时进行数据的同步复制,支持多级复制和增量复制,master-slave机制是redis进行ha的重要手段。

4.单线程请求,所有命令串行执行,并发情况下不需要考虑数据一致性问题。

5.支持pub/sub消息订阅机制,可以用来进行消息订阅与通知。

6.支持简单的事务需求,但业界使用场景很少,并不成熟。

1.redis只能使用单线程,性能受限于cpu性能,故单实例cpu最高才可能达到5-6wqps每秒(取决于数据结构,数据大小以及服务器硬件性能,日常环境中qps高峰大约在1-2w左右)。

2.支持简单的事务需求,但业界使用场景很少,并不成熟,既是优点也是缺点。

3.redis在string类型上会消耗较多内存,可以使用dict(hash表)压缩存储以降低内存耗用。

1.更高的写负载,mongodb拥有更高的插入速度。

2.处理很大的规模的单表,当数据表太大的时候可以很容易的分割表。

3.高可用性,设置m-s不仅方便而且很快,mongodb还可以快速、安全及自动化的实现节点(数据中心)故障转移。

4.快速的查询,mongodb支持二维空间索引,比如管道,因此可以快速及精确的从指定位置获取数据。mongodb在启动后会将数据库中的数据以文件映射的方式加载到内存中。如果内存资源相当丰富的话,这将极大地提高数据库的查询速度。

5.非结构化数据的爆发增长,增加列在有些情况下可能锁定整个数据库,或者增加负载从而导致性能下降,由于mongodb的弱数据结构模式,添加1个新字段不会对旧表格有任何影响,整个过程会非常快速。

3.mongodb没有成熟的维护工具。

三者的性能都比较高,总的来讲:memcached和redis差不多,要高于mongodb。

redis丰富一些,数据操作方面,redis更好一些,较少的网络io次数。

mongodb支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富。

memcached可以修改最大可用内存,采用lru算法。

redis在2.0版本后增加了自己的vm特性,突破物理内存的限制;可以对key value设置过期时间(类似memcached)。

mongodb适合大数据量的存储,依赖操作系统vm做内存管理,吃内存也比较厉害,服务不要和别的服务在一起。

memcached本身没有数据冗余机制,也没必要;对于故障预防,采用依赖成熟的hash或者环状的算法,解决单点故障引起的抖动问题。

redis,依赖客户端来实现分布式读写;主从复制时,每次从节点重新连接主节点都要依赖整个快照,无增量复制,因性能和效率问题,所以单点问题比较复杂;不支持自动sharding,需要依赖程序设定一致hash 机制。一种替代方案是,不用redis本身的复制机制,采用自己做主动复制(多份存储),或者改成增量复制的方式(需要自己实现),一致性问题和性能的权衡。

memcached不支持,通常用在做缓存,提升性能。

redis支持(快照、aof):依赖快照进行持久化,aof增强了可靠性的同时,对性能有所影响。

mongodb从1.8版本开始采用binlog方式支持持久化的可靠性。

memcached在并发场景下,用cas保证一致性。

redis事务支持比较弱,只能保证事务中的每个操作连续执行。

mongodb内置了数据分析的功能(mapreduce),其他两者不支持。

memcached:用于在动态系统中减少数据库负载,提升性能;做缓存,提高性能(适合读多写少,对于数据量比较大,可以采用sharding)。

redis:数据量较小的高性能操作和运算上。

mongodb:主要解决海量数据的访问效率问题。

1.若是简单的存取key-value(主要是读)这样的数据用memcached好一些。若是要支持数据持久化,量也不大,操作很频繁,多数据类型(如集合、散列之类的),用列表类型做队列之类的高级应用,就用redis,但如果是数据量比较大时就采用mongodb。

3.云数据库memcached版实例中的数据是存储在内存中的,当出现宕机、机房断电等意外,或是云数据库memcached版实例在正常升级维护时,内存中的数据均会丢失。因此,云数据库memcached版不能作为持久化的数据存储服务使用。redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据,实现持久化。

4.对于redis和mongodb来说,大家一般称之为redis缓存、mongodb数据库。redis主要把数据存储在内存中,其“缓存”的性质远大于其“数据存储“的性质,其中数据的增删改查也只是像变量操作一样简单;mongodb却是一个“存储数据”的系统,增删改查可以添加很多条件,就像sql数据库一样灵活。

5.mongodb和redis都是nosql,采用结构型数据存储。二者在使用场景中,存在一定的区别,这也主要由于二者在内存映射的处理过程,持久化的处理方法不同。mongodb建议集群部署,更多的考虑到集群方案,redis更偏重于进程顺序写入,虽然支持集群,也仅限于主-从模式

这篇文章我想和你聊一聊 Redis 的架构演化之路。

现如今 Redis 变得越来越流行,几乎在很多项目中都要被用到,不知道你在使用 Redis 时,有没有思考过,Redis 到底是如何稳定、高性能地提供服务的?

你也可以尝试回答一下以下这些问题:

  • 我使用 Redis 的场景很简单,只使用单机版 Redis 会有什么问题吗?
  • 我的 Redis 故障宕机了,数据丢失了怎么办?如何能保证我的业务应用不受影响?
  • 为什么需要主从集群?它有什么优势?
  • 什么是分片集群?我真的需要分片集群吗?

如果你对 Redis 已经有些了解,肯定也听说过数据持久化、主从复制、哨兵这些概念,它们之间又有什么区别和联系呢?

如果你存在这样的疑惑,这篇文章,我会从 0 到 1,再从 1 到 N,带你一步步构建出一个稳定、高性能的 Redis 集群。

在这个过程中,你可以了解到 Redis 为了做到稳定、高性能,都采取了哪些优化方案,以及为什么要这么做?

掌握了这些原理,这样平时你在使用 Redis 时,就能够做到「游刃有余」。

这篇文章干货很多,希望你可以耐心读完。

补充:Redis原理可以参考一下这篇文章:

从最简单的开始:单机版 Redis

首先,我们从最简单的场景开始。

假设现在你有一个业务应用,需要引入 Redis 来提高应用的性能,此时你可以选择部署一个单机版的 Redis 来使用,就像这样:

这个架构非常简单,你的业务应用可以把 Redis 当做缓存来使用,从 MySQL 中查询数据,然后写入到 Redis 中,之后业务应用再从 Redis 中读取这些数据,由于 Redis 的数据都存储在内存中,所以这个速度飞快。

如果你的业务体量并不大,那这样的架构模型基本可以满足你的需求。是不是很简单?

随着时间的推移,你的业务体量逐渐发展起来了,Redis 中存储的数据也越来越多,此时你的业务应用对 Redis 的依赖也越来越重。

但是,突然有一天,你的 Redis 因为某些原因宕机了,这时你的所有业务流量,都会打到后端 MySQL 上,这会导致你的 MySQL 压力剧增,严重的话甚至会压垮 MySQL。

我猜你的方案肯定是,赶紧重启 Redis,让它可以继续提供服务。

但是,因为之前 Redis 中的数据都在内存中,尽管你现在把 Redis 重启了,之前的数据也都丢失了。重启后的 Redis 虽然可以正常工作,但是由于 Redis 中没有任何数据,业务流量还是都会打到后端 MySQL 上,MySQL 的压力还是很大。

这可怎么办?你陷入了沉思。

有没有什么好的办法解决这个问题?

既然 Redis 只把数据存储在内存中,那是否可以把这些数据也写一份到磁盘上呢?

如果采用这种方式,当 Redis 重启时,我们把磁盘中的数据快速恢复到内存中,这样它就可以继续正常提供服务了。

是的,这是一个很好的解决方案,这个把内存数据写到磁盘上的过程,就是「数据持久化」。

现在,你设想的 Redis 数据持久化是这样的:

但是,数据持久化具体应该怎么做呢?

我猜你最容易想到的一个方案是,Redis 每一次执行写操作,除了写内存之外,同时也写一份到磁盘上,就像这样:

没错,这是最简单直接的方案。

但仔细想一下,这个方案有个问题:客户端的每次写操作,既需要写内存,又需要写磁盘,而写磁盘的耗时相比于写内存来说,肯定要慢很多!这势必会影响到 Redis 的性能。

我们可以这样优化:Redis 写内存由主线程来做,写内存完成后就给客户端返回结果,然后 Redis 用另一个线程去写磁盘,这样就可以避免主线程写磁盘对性能的影响。

这确实是一个好方案。除此之外,我们可以换个角度,思考一下还有什么方式可以持久化数据?

这时你就要结合 Redis 的使用场景来考虑了。

回忆一下,我们在使用 Redis 时,通常把它用作什么场景?

把 Redis 当做缓存来用,意味着尽管 Redis 中没有保存全量数据,对于不在缓存中的数据,我们的业务应用依旧可以通过查询后端数据库得到结果,只不过查询后端数据的速度会慢一点而已,但对业务结果其实是没有影响的。

基于这个特点,我们的 Redis 数据持久化还可以用「数据快照」的方式来做。

简单来讲,你可以这么理解:

  1. 你把 Redis 想象成一个水杯,向 Redis 写入数据,就相当于往这个杯子里倒水
  2. 此时你拿一个相机给这个水杯拍一张照片,拍照的这一瞬间,照片中记录到这个水杯中水的容量,就是水杯的数据快照

也就是说,Redis 的数据快照,是记录某一时刻下 Redis 中的数据,然后只需要把这个数据快照写到磁盘上就可以了。

它的优势在于,只在需要持久化时,把数据「一次性」写入磁盘,其它时间都不需要操作磁盘。

基于这个方案,我们可以定时给 Redis 做数据快照,把数据持久化到磁盘上。

其实,上面说的这些持久化方案,就是 Redis 的「RDB」和「AOF」:

  • RDB:只持久化某一时刻的数据快照到磁盘上(创建一个子进程来做)
  • AOF:每一次写操作都持久到磁盘(主线程写内存,根据策略可以配置由主线程还是子线程进行数据持久化)

它们的区别除了上面讲到的,还有以下特点:

  1. RDB 采用二进制 + 数据压缩的方式写磁盘,这样文件体积小,数据恢复速度也快
  2. AOF 记录的是每一次写命令,数据最全,但文件体积大,数据恢复速度慢

如果让你来选择持久化方案,你可以这样选择:

  1. 如果你的业务对于数据丢失不敏感,采用 RDB 方案持久化数据
  2. 如果你的业务对数据完整性要求比较高,采用 AOF 方案持久化数据

假设你的业务对 Redis 数据完整性要求比较高,选择了 AOF 方案,那此时你又会遇到这些问题:

  1. AOF 记录每一次写操作,随着时间增长,AOF 文件体积会越来越大
  2. 这么大的 AOF 文件,在数据恢复时变得非常慢

这怎么办?数据完整性要求变高了,恢复数据也变困难了?有没有什么方法,可以缩小文件体积?提升恢复速度呢?

我们继续来分析 AOF 的特点。

由于 AOF 文件中记录的都是每一次写操作,但对于同一个 key 可能会发生多次修改,我们只保留最后一次被修改的值,是不是也可以?

是的,这就是我们经常听到的「AOF rewrite」,你也可以把它理解为 AOF 「瘦身」。

我们可以对 AOF 文件定时 rewrite,避免这个文件体积持续膨胀,这样在恢复时就可以缩短恢复时间了。

再进一步思考一下,还有没有办法继续缩小 AOF 文件?

回顾一下我们前面讲到的,RDB 和 AOF 各自的特点:

  1. RDB 以二进制 + 数据压缩方式存储,文件体积小
  2. AOF 记录每一次写命令,数据最全

我们可否利用它们各自的优势呢?

当然可以,这就是 Redis 的「混合持久化」。

具体来说,当 AOF rewrite 时,Redis 先以 RDB 格式在 AOF 文件中写入一个数据快照,再把在这期间产生的每一个写命令,追加到 AOF 文件中。因为 RDB 是二进制压缩写入的,这样 AOF 文件体积就变得更小了。

此时,你在使用 AOF 文件恢复数据时,这个恢复时间就会更短了!

Redis 4.0 以上版本才支持混合持久化。

这么一番优化,你的 Redis 再也不用担心实例宕机了,当发生宕机时,你就可以用持久化文件快速恢复 Redis 中的数据。

仔细想一下,虽然我们已经把持久化的文件优化到最小了,但在恢复数据时依旧是需要时间的,在这期间你的业务应用还是会受到影响,这怎么办?

我们来分析有没有更好的方案。

一个实例宕机,只能用恢复数据来解决,那我们是否可以部署多个 Redis 实例,然后让这些实例数据保持实时同步,这样当一个实例宕机时,我们在剩下的实例中选择一个继续提供服务就好了。

没错,这个方案就是接下来要讲的「主从复制:多副本」。

此时,你可以部署多个 Redis 实例,架构模型就变成了这样:

我们这里把实时读写的节点叫做 master,另一个实时同步数据的节点叫做 slave。

采用多副本的方案,它的优势是:

  1. 缩短不可用时间:master 发生宕机,我们可以手动把 slave 提升为 master 继续提供服务
  2. 提升读性能:让 slave 分担一部分读请求,提升应用的整体性能

这个方案不错,不仅节省了数据恢复的时间,还能提升性能,那它有什么问题吗?

其实,它的问题在于:当 master 宕机时,我们需要「手动」把 slave 提升为 master,这个过程也是需要花费时间的。

虽然比恢复数据要快得多,但还是需要人工介入处理。一旦需要人工介入,就必须要算上人的反应时间、操作时间,所以,在这期间你的业务应用依旧会受到影响。

怎么解决这个问题?我们是否可以把这个切换的过程,变成自动化呢?

对于这种情况,我们需要一个「故障自动切换」机制,这就是我们经常听到的「哨兵」所具备的能力。

现在,我们可以引入一个「观察者」,让这个观察者去实时监测 master 的健康状态,这个观察者就是「哨兵」。

  1. 哨兵每间隔一段时间,询问 master 是否正常
  2. master 正常回复,表示状态正常,回复超时表示异常
  3. 哨兵发现异常,发起主从切换

有了这个方案,就不需要人去介入处理了,一切就变得自动化了,是不是很爽?

但这里还有一个问题,如果 master 状态正常,但这个哨兵在询问 master 时,它们之间的网络发生了问题,那这个哨兵可能会误判。

答案是,我们可以部署多个哨兵,让它们分布在不同的机器上,它们一起监测 master 的状态,流程就变成了这样:

  1. 多个哨兵每间隔一段时间,询问 master 是否正常
  2. master 正常回复,表示状态正常,回复超时表示异常
  3. 一旦有一个哨兵判定 master 异常(不管是否是网络问题),就询问其它哨兵,如果多个哨兵(设置一个阈值)都认为 master 异常了,这才判定 master 确实发生了故障
  4. 多个哨兵经过协商后,判定 master 故障,则发起主从切换

所以,我们用多个哨兵互相协商来判定 master 的状态,这样一来,就可以大大降低误判的概率。

哨兵协商判定 master 异常后,这里还有一个问题:由哪个哨兵来发起主从切换呢?

答案是,选出一个哨兵「领导者」,由这个领导者进行主从切换。

问题又来了,这个领导者怎么选?

想象一下,在现实生活中,选举是怎么做的?

在选举哨兵领导者时,我们可以制定这样一个选举规则:

  1. 每个哨兵都询问其它哨兵,请求对方为自己投票
  2. 每个哨兵只投票给第一个请求投票的哨兵,且只能投票一次
  3. 首先拿到超过半数投票的哨兵,当选为领导者,发起主从切换

其实,这个选举的过程就是我们经常听到的:分布式系统领域中的「共识算法」。

我们在多个机器部署哨兵,它们需要共同协作完成一项任务,所以它们就组成了一个「分布式系统」。

在分布式系统领域,多个节点如何就一个问题达成共识的算法,就叫共识算法。

在这个场景下,多个哨兵共同协商,选举出一个都认可的领导者,就是使用共识算法完成的。

这个算法还规定节点的数量必须是奇数个,这样可以保证系统中即使有节点发生了故障,剩余超过「半数」的节点状态正常,依旧可以提供正确的结果,也就是说,这个算法还兼容了存在故障节点的情况。

共识算法在分布式系统领域有很多,例如 Paxos、Raft,哨兵选举领导者这个场景,使用的是 Raft 共识算法,因为它足够简单,且易于实现。

现在,我们用多个哨兵共同监测 Redis 的状态,这样一来,就可以避免误判的问题了,架构模型就变成了这样:

好了,到这里我们先小结一下。

你的 Redis 从最简单的单机版,经过数据持久化、主从多副本、哨兵集群,这一路优化下来,你的 Redis 不管是性能还是稳定性,都越来越高,就算节点发生故障,也不用担心了。

你的 Redis 以这样的架构模式部署,基本上就可以稳定运行很长时间了。

随着时间的发展,你的业务体量开始迎来了爆炸性增长,此时你的架构模型,还能够承担这么大的流量吗?

  1. 稳定性:Redis 故障宕机,我们有哨兵 + 副本,可以自动完成主从切换
  2. 性能:读请求量增长,我们可以再部署多个 slave,读写分离,分担读压力
  3. 性能:写请求量增长,但我们只有一个 master 实例,这个实例达到瓶颈怎么办?

看到了么,当你的写请求量越来越大时,一个 master 实例可能就无法承担这么大的写流量了。

要想完美解决这个问题,此时你就需要考虑使用「分片集群」了。

简单来讲,一个实例扛不住写压力,那我们是否可以部署多个实例,然后把这些实例按照一定规则组织起来,把它们当成一个整体,对外提供服务,这样不就可以解决集中写一个实例的瓶颈问题吗?

所以,现在的架构模型就变成了这样:

现在问题又来了,这么多实例如何组织呢?

  1. 每个节点各自存储一部分数据,所有节点数据之和才是全量数据
  2. 制定一个路由规则,对于不同的 key,把它路由到固定一个实例上进行读写

而分片集群根据路由规则所在位置的不同,还可以分为两大类:

客户端分片指的是,key 的路由规则放在客户端来做,就是下面这样:

这个方案的缺点是,客户端需要维护这个路由规则,也就是说,你需要把路由规则写到你的业务代码中。

如何做到不把路由规则耦合在业务代码中呢?

你可以这样优化,把这个路由规则封装成一个模块,当需要使用时,集成这个模块就可以了。

Redis Cluster 内置了哨兵逻辑,无需再部署哨兵。

当你使用 Redis Cluster 时,你的业务应用需要使用配套的 Redis SDK,这个 SDK 内就集成好了路由规则,不需要你自己编写了。

这种方案指的是,路由规则不放在客户端来做,而是在客户端和服务端之间增加一个「中间代理层」,这个代理就是我们经常听到的 Proxy。

而数据的路由规则,就放在这个 Proxy 层来维护。

这样一来,你就无需关心服务端有多少个 Redis 节点了,只需要和这个 Proxy 交互即可。

Proxy 会把你的请求根据路由规则,转发到对应的 Redis 节点上,而且,当集群实例不足以支撑更大的流量请求时,还可以横向扩容,添加新的 Redis 实例提升性能,这一切对于你的客户端来说,都是透明无感知的。

业界开源的 Redis 分片集群方案,例如 Twemproxy、Codis 就是采用的这种方案。

分片集群在数据扩容时,还涉及到了很多细节,这块内容不是本文章重点,所以暂不详述。

至此,当你使用分片集群后,对于未来更大的流量压力,都可以从容面对了!

好了,我们来总结一下,我们是如何一步步构建一个稳定、高性能的 Redis 集群的。

首先,在使用最简单的单机版 Redis 时,我们发现当 Redis 故障宕机后,数据无法恢复的问题,因此我们想到了「数据持久化」,把内存中的数据也持久化到磁盘上一份,这样 Redis 重启后就可以从磁盘上快速恢复数据。

在进行数据持久化时,我们又面临如何更高效地将数据持久化到磁盘的问题。之后我们发现 Redis 提供了 RDB 和 AOF 两种方案,分别对应了数据快照和实时的命令记录。当我们对数据完整性要求不高时,可以选择 RDB 持久化方案。如果对于数据完整性要求较高,那么可以选择 AOF 持久化方案。

但是我们又发现,AOF 文件体积会随着时间增长变得越来越大,此时我们想到的优化方案是,使用 AOF rewrite 的方式对其进行瘦身,减小文件体积,再后来,我们发现可以结合 RDB 和 AOF 各自的优势,在 AOF rewrite 时使用两者结合的「混合持久化」方式,又进一步减小了 AOF 文件体积。

之后,我们发现尽管可以通过数据恢复的方式还原数据,但恢复数据也是需要花费时间的,这意味着业务应用还是会受到影响。我们进一步优化,采用「多副本」的方案,让多个实例保持实时同步,当一个实例故障时,可以手动把其它实例提升上来继续提供服务。

但是这样也有问题,手动提升实例上来,需要人工介入,人工介入操作也需要时间,我们开始想办法把这个流程变得自动化,所以我们又引入了「哨兵」集群,哨兵集群通过互相协商的方式,发现故障节点,并可以自动完成切换,这样就大幅降低了对业务应用的影响。

最后,我们把关注点聚焦在如何支撑更大的写流量上,所以,我们又引入了「分片集群」来解决这个问题,让多个 Redis 实例分摊写压力,未来面对更大的流量,我们还可以添加新的实例,横向扩展,进一步提升集群的性能。

至此,我们的 Redis 集群才得以长期稳定、高性能的为我们的业务提供服务。

这里我画了一个思维导图,方便你更好地去理解它们之间的关系,以及演化的过程。

看到这里,我想你对如何构建一个稳定、高性能的 Redis 集群问题时,应该会有自己的见解了。

其实,这篇文章所讲的优化思路,围绕的主题就是「架构设计」的核心思想:

  • 高性能:读写分离、分片集群
  • 高可用:数据持久化、多副本、故障自动切换
  • 易扩展:分片集群、横向扩展

当我们讲到哨兵集群、分片集群时,这还涉及到了「分布式系统」相关的知识:

  • 分布式共识:哨兵领导者选举
  • 负载均衡:分片集群数据分片、数据路由

当然,除了 Redis 之外,对于构建任何一个数据集群,你都可以沿用这个思路去思考、去优化,看看它们到底是如何做的。

例如当你在使用 MySQL 时,你可以思考一下 MySQL 与 Redis 有哪些不同?MySQL 为了做到高性能、高可用,又是如何做的?其实思路都是类似的。

我们现在到处可见分布式系统、数据集群,我希望通过这篇文章,你可以理解这些软件是如何一步步演化过来的,在演化过程中,它们遇到了哪些问题,为了解决这些问题,这些软件的设计者设计了怎样的方案,做了哪些取舍?

你只有了解了其中的原理,掌握了分析问题、解决问题的能力,这样在以后的开发过程中,或是学习其它优秀软件时,就能快速地找到「重点」,在最短的时间掌握它,并能在实际应用中发挥它们的优势。

其实这个思考过程,也是做「架构设计」的思路。在做软件架构设计时,你面临的场景就是发现问题、分析问题、解决问题,一步步去演化、升级你的架构,最后在性能、可靠性方面达到一个平衡。虽然各种软件层出不穷,但架构设计的思想不会变,我希望你真正吸收的是这些思想,这样才可以做到以不变应万变。

我是 Kaito,是一个对于技术有思考的资深后端程序员,在我的文章中,我不仅会告诉你一个技术点是什么,还会告诉你为什么这么做?我还会尝试把这些思考过程,提炼成通用的方法论,让你可以应用在其它领域中,做到举一反三。

我要回帖

更多关于 leader选举算法 的文章

 

随机推荐