关系经济人类预测化学自然
自然科学
知识物理
化学生物
地理解释
预测理解
本质社会
人类现象
行为研究
经济政治
心理结构
关系指导
人文遗产

一种以特征为依据的数据分片策略

2月22日 温柔冢投稿
  假如您有一个应用程序,随着业务越来越有起色,系统所牵涉到的数据量也就越来越大,此时您要涉及到对系统进行伸缩(Scale)的问题了。一种典型的扩展方法叫做向上伸缩(ScaleUp),它的意思是通过使用更好的硬件来提高系统的性能参数。而另一种方法则叫做向外伸缩(ScaleOut),它是指通过增加额外的硬件(如服务器)来达到相同的效果。从硬件成本还是系统极限的角度来说,向外伸缩一般都会优于向上伸缩,因此大部分上规模的系统都会在一定程度上考虑向外的方式。由于许多系统的瓶颈都处在数据存储上,因此一种叫做数据分片(DatabaseSharding)的数据架构方式应运而生,本文便会讨论这种数据架构方式的一种比较典型的实现方式。
  简介
  数据分片,自然便是将整体数据分摊在多个存储设备(下文统称为数据分区或分区)上,这样每个存储设备的数据量相对就会小很多,以此满足系统的性能需求。值得注意的是,系统分片的策略有很多,例如常见的有以下几种:
  根据ID特征:例如对记录的ID取模,得到的结果是几,那么这条记录就放在编号为几的数据分区上。
  根据时间范围:例如前100万个用户数据在第1个分区中,第二个100万用户数据放在第2个分区中。
  基于检索表:根据ID先去一个表内找到它所在的分区,然后再去目标分区进行查找。
  在这些数据分片策略之中没有哪个有绝对的优势,选择哪种策略完全是根据系统的业务或是数据特征来确定的。值得强调的是:数据分片不是银弹,它对系统的性能和伸缩性(Scalability)带来一定好处的同时,也会对系统开发带来许多复杂度。例如,有两条记录分别处在不同的服务器上,那么如果有一个业务是为它们建立一个关联,那么很可能表示关联的记录就必须在两个分区内各放一条。另外,如果您重视数据的完整性,那么跨数据分区的事务又立即变成了性能杀手。最后,如果有一些需要进行全局查找的业务,光有数据分片策略也很难对系统性能带来什么优势。
  数据分片虽然重要,但在使用之前一定要三思而后行。一旦踏上这艘贼船,往往不成功便成仁,很难回头。在我的经验里,一个滥用数据分片策略而事倍功半的项目给我留下了非常深刻的印象(当然也有成功的啦),因此目前我对待数据分片策略变得愈发谨慎。
  那么现在,我们便来讨论一种比较常见的数据分片策略。
  策略描述
  这里我先描述一个极其简单的业务:
  系统中有用户,用户可以发表文章,文章会有评论
  可以根据用户查找文章
  可以根据文章查找评论
  那么,如果我要对这样一个系统进行数据分片又该怎么做呢?这里我们可以使用上面提到的第一种方式,即对记录的ID取模,并根据结果选择数据所在的分区。根据后两条业务中描述的查询要求,我们会为分区策略补充这样的规则:
  某个用户的所有文章,与这个用户处在同一数据分区内。
  某篇文章的所有评论,与这篇文章处在用一数据分区内。
  您可能会说,似乎只要保证相同用户文章在同一个数据分区内就行了,不是吗?没错,不过我这里让文章和用户在同一个分区内,也是为了方便许多额外的操作(例如在关系数据库中进行连接)。那么假设我们有4个数据分区,那么它们内部的条目可能便是:
  分区0分区1
  User4
  Article8
  Article12
  Comment4
  Comment16
  User12
  Article4
  User1
  Article5
  Article9
  Comment13
  Comment17
  User5
  Article13
  分区2分区3
  User2
  Article10
  Article14
  Comment6
  Comment10
  User10
  Article4
  User7
  Article7
  Article11
  Comment3
  Comment15
  User11
  Article4
  在ID为0的分区中,所有对象的ID模4均为0,其他分区里的对象也有这样的规律。那么好,在实际应用中,如果我们需要查找ID为2的用户,便去第2分区搜索便是;如果要查找ID为8的文章的所有评论那么也只要去第0分区进行一次查询即可。既然查询不成问题,那么我们该如何添加新记录呢?其实这也不难,只要:
  添加新用户时,随机选择一个数据分区
  添加新文章时,选择文章作者所在分区(可根据Article的UserID求模得到)
  添加新评论时,选择文章所在分区(可根据Comment的ArticleID求模得到)
  但是,我们又如何保证新纪录的ID正好满足我们的分区规律?例如我们向第3分区添加的新数据,则它的ID必须是3、7、11等等。以前,我们可能会使用数据库的自增列作为ID的值,但这似乎不能满足我们取模的要求。以前我们可能还会使用GUID,但是我们如何生成一个被4模于3的GUID呢?其实我们还是可以使用自增ID来解决这个问题,只不过需要进行一些简单的设置。例如在SQLServer中,默认的自增ID属性为IDENTITY(1,1),表示ID从1开始,以1为间距自动增长。于是我们在创建数据分区的时候,每个自增列的属性则可以设置为:
  分区0:IDENTITY(4,4)
  分区1:IDENTITY(1,4)
  分区2:IDENTITY(2,4)
  分区3:IDENTITY(3,4)
  这样,ID方面的问题便交由数据库来关心吧,我们的使用方式和以前并没有什么区别。
  缺陷
  那么这个数据分片策略有什么缺陷呢?当然缺陷还是有很多啦,只是大多数问题可能还是要和业务放在一起考虑时才会凸显出来。不过有一个问题倒和业务关系不大:如果数据继续增长,单个数据分区的数据量也超标了,怎么办?
  自然,继续拆分咯。那么我们使用什么分区规则呢?和原先一致吗?我们举个例子便知。假设我们原有4个分区,有一个ID为1的用户落在第1分区里,他的文章也都在这个分区里,ID分别是1、5、9、13、17等等。于是在某一天,我们需要将分区数量提高到5个(财力有限,一台一台来吧),在重新计算每篇文章所在的分区之后,我们忽然发现:
  ID为1的文章,模5余1,处在分区1。
  ID为5的文章,模5余0,处在分区0。
  ID为9的文章,模5余4,处在分区4。
  ID为13的文章,模5余3,处在分区3。
  ID为17的文章,模5余2,处在分区2。
  呼,5个分区都齐了!这说明,如果我们保持记录原来的ID不变,是没有办法直接使用之前的分区规则无论您扩展成几个分区,(即便是从4个到8个)也只能缓解也不能解决这个情况。那么这时候该如何是好呢?例如,我们可以重新分配记录,改变原有ID,只是这么做会产生一个问题,便是外部URL可能也会随着ID一起改变,这样对SEO的折损很大。为此,我们可以制作一个查询表:例如在查询小于1234567的ID时(这是老系统的最大ID),假设是100,则根据查询表得知这条记录的新ID为7654321,再以此去数据源进行查找。解决这类问题的方法还有几种,但无论怎么做都会对新系统带来额外的复杂度。而且,一次扩展也罢,如果以后还要有所扩展呢?
  有朋友可能会说,取模自然会带来这样的问题,那么为什么不用一致性哈希(ConsistentHash)呢?现在一致性哈希是个很流行的东西,和Memcached一样,如果不用上就会被一些高级架构师所鄙视。不过在这里一致性哈希也不能解决问题。一致性哈希的目的,是希望在增加服务器的时候降低数据移动规模,让尽可能多的数据保留在原有的服务器上。而我们现在的问题却是在增加服务器的时候,让特征相同的数据同样放在一起。两个目标不同,这并不是一致性哈希的应用场景。
  我在以前的一个项目中曾经用过这样的方法:根据对访问量与数据量的预估,我们认为使用最多24个分区便一定可以满足性能要求(为什么是24个?因为它能被许多数字整除)。于是,从项目第一次在生产环境中部署时便创建了24个数据分区,只不过一开始只用了2台服务器,每台服务器放置12个数据分区。待以后需要扩展时,则将数据分区均匀地迁移到新的服务器上即可。我们团队当时便是用这种方法避免尴尬的数据分配问题。
  没错,数据分区的数目是个限制,但您真认为,24个数据分区还是无法满足您的项目需求吗?要知道,需要用上24个数据分区的项目,一般来说本身已经有充分的时间和经济实力进行架构上的重大调整(也该调整了,几乎没有什么架构可以满足各种数据规模的需求)。此外,无论是系统优化还是数据分片都可以同时运用其他手段。
  不过,我们目前还是想办法解决这个问题吧。
  策略改进
  我们之所以会遇到上面这个问题,在于我们没有选择好合适的策略,这个策略把一些重要的要求给具体化了,导致具体化后的结果在外部条件改变的时候,却无法重新满足原有的要求。还是以前面的案例来说明问题,其实我们要求其实是:
  某个用户的所有文章,与这个用户处在同一数据分区内。
  某篇文章的所有评论,与这篇文章处在用一数据分区内。
  而我们具体化以后的结果却是:
  某个用户的所有文章ID,与这个用户的ID模4后的余数相同。
  某篇文章的所有评论ID,与这篇文章的ID模4后的余数相同。
  之所以能如此具体化,这是因为有4个分区这样的前提条件在,一旦这个前提条件发生了改变,则杯具无法避免。因此,我们在制定规则的时候,其实不应该把前提条件给过分的具体化具体化可以,但不能过度,得留有一定空间(这个稍后再谈)。打个比方,还是前面的条件(XX和XX处在同一数据分区内),但我们换一种具体化的方式:
  某个用户的所有文章ID的前缀,便是这个用户的ID。例如,ID为1的用户的所有文章,其ID便可能是1A1、1A2、1A3
  某篇文章的所有评论ID,与这个文章的ID使用相同前缀。例如,ID为3A1的文章的所有评论,其ID便可能是3C1、3C2、3C3
  使用这个策略,我们便可以保证与某个用户相关的所有数据都共享相同的特征(ID的前缀都相同),然后我们便可以根据这个特征来选择分区例如,还是以取模的方式。此时,我们已经确保了相同分区内的所有数据都具备相同的特征,即便分区数量有所调整,我们也只需要根据特征重新计算分区即可,影响不大。而以前为什么不行?因为模4的余数只是结果而不是特征,这里的特征应该是追本溯源后的用户ID相同,而这一点已经体现在新的策略中了。
  还是通过图示来说明问题吧。假设原有4个分区,使用取模的策略:
  分区0分区1
  User4
  Article4A1
  Article4A2
  Comment4C1
  Comment4C2
  User12
  Article12A3
  User1
  Article1A4
  Article1A5
  Comment1C3
  Comment1C4
  User5
  Article5A6
  分区2分区3
  User2
  Article2A7
  Article2A8
  Comment2C5
  Comment2C6
  User10
  Article10A9
  User7
  Article7A10
  Article7A11
  Comment7C7
  Comment7C8
  User11
  Article11A12
  当分区数量调整为5个之后(为了避免分区3空缺,我又补充了一些对象):
  分区0分区1
  User10
  Article10A9
  User5
  Article5A6
  User1
  Article1A4
  Article1A5
  Comment1C3
  Comment1C4
  User11
  Article11A12
  分区2分区3
  User2
  Article2A7
  Article2A8
  Comment2C5
  Comment2C6
  User12
  Article12A3
  User7
  Article7A10
  Article7A11
  Comment7C7
  Comment7C8
  User8
  Article8A12
  Article8A13
  Comment8C9
  Comment7C10
  分区4
  User4
  Article4A1
  Article4A2
  Comment4C1
  Comment4C2
  是不是很合理?
  值得一提的是,只要满足了特征这个要求,其实选择分区的方式并没有什么限制。例如,我们可以不用取模的方式,而是使用一致性哈希没错,这里就是一致性哈希的使用场景了。在利用一致性哈希来选择分区之后,在添加服务器的情况下便可以相对减少数据的迁移数量了。
  当然,在实现时还可以运用一些技巧。例如,我们的特征并非一定要把用户ID作为前缀毕竟用户ID可能比较长,作为ID前缀还真有些难看(请想象把GUID作为ID前缀,再加上另一个GUID作为ID主体的情景)。此时,我们可以把前提条件先进行一定程度的具体化(但就像之前提到的,不能过度),例如我们可以把用户ID先进行取模,可能是1000万,便可以得到一个落在较大区间范围内的数字。然后,再把这个数字作BASE64编码,一下子前缀就缩小为4个字符以内了。而且,1000万这个区间范围,无论是使用取模还是一致性哈希的方式来选择分区都非常可行,一般不会造成什么问题。
  总结
搜索 投诉 评论 转载

五福花梅花象征着什么寓意最近很多人对梅花非常的感兴趣,也的的确确是这样的,梅花在中国的古代非常的受欢迎,梅花话说又被称作为五福花,那么有人要问了,竟然被称作是五福花,那象征着哪五福呢?这个问题也比较有……母乳喂养需要遵循哪些原则母乳喂养对于宝宝来说可以说是最安全最有营养的食物,宝宝身体成长所需要的各种营养,通过母乳能够很好的吸收,不过母乳在喂养的时候也是需要注意的,有很多的原则需要遵守。操作方法……成人用品有哪些种类相信成人用品对大家并不陌生,但您真的知道成人用品的具体种类吗?其实成人用品的种类比较多,下面给大家说说成人用品的分类,建议购买前一定要多了解。成人用品包括BDSM用品、性……情趣用品绝对会让男人遐想无限欲火喷张黑色给人的感觉既神秘又酷感十足,还能带来致命的性感诱惑,如果给女性的黑色内衣加上蕾丝装饰,更能增添女性娇媚性感的气息。把黑色的性感蕾丝内衣作为男女助性的情趣用品,绝对会让男人遐……月季盆栽病虫害防治方法月季黑斑病:病原菌主要侵染叶部,也危害叶柄、嫩枝、花梗、花瓣。发病初期叶片出现黑色斑点,逐渐扩大成紫褐色边缘呈放射状的病斑,病斑上散生许多黑色颗粒小点,后期病斑相连,叶片变黄脱……学生大会讲话稿模板八亲爱的同学们:大家早上好!在结束了轻松愉快的寒假后,我们又迎来了一个崭新的学期。回顾上一个学年,在全体师生的共同努力下,我们的内务卫生、仪容仪表、上课出勤、课堂纪律、素质……不得不去的经典园林拙政园不得不去的经典园林:拙政园不得不去的经典园林拙政园是中国园林艺术的经典之作,被誉为天下园林之母。1961年被国务院列为全国第一批重点文物保护单位,与颐和园、避暑山庄……大数据预测小鸣单车毛用车的策略可行不伴随着云概念的诞生,大数据逐渐进入了人们的视野,时至今日,想必对很多人(特别是互联网行业的从业者)来说,大数据已不陌生。我真正接触大数据的时间并不长,认识自然也比较有限。不过,……天下苦流量久矣通过本文,你会被普及电商商家平台流量争夺历史,还会了解到私域流量的whatwhyhow、各平台商家引流的套路等,字数较多,还有点干。最近,身边越来越多的人……一种以特征为依据的数据分片策略假如您有一个应用程序,随着业务越来越有起色,系统所牵涉到的数据量也就越来越大,此时您要涉及到对系统进行伸缩(Scale)的问题了。一种典型的扩展方法叫做向上伸缩(ScaleUp……如何巧妙的布艺窗帘搭配使房间宽敞明亮如何通过搭配家居环境,来掩盖房间缺陷,同时美化居室环境。而下面本文为大家介绍几种关于如何通过布艺窗帘搭配改善居室的小知识。一、通过选择竖条图案的窗饰使房间增高如果房……最详细的电脑系统安装教程零基础开始看嗨咯!大家好,欢迎观看本期技术小进的电脑小知识。今天给大家带来的内容很有用哦,就是如何自己去动手安装电脑系统,最后还有惊喜哦!如今啊,电脑成为家家户户,不管是公司,还是学……
老人为什么易患口腔溃疡该如何治疗产后风是怎么回事产后风如何预防鼠年宝宝取名五行取名年按照五行给宝宝取名阴茎力量锻炼的方法有哪些呢清王朝最有作为的皇帝康熙最爱的女人是谁太子李弘死后唐高宗李治做了什么荒诞不经的事揭秘著名将领庞涓其实是个十足的自恋狂锦衣之下小说原著剧情内容是什么剧透治疗宫颈糜烂的物理治疗如何捕捉灵感数学是什么数学的本质是什么老人吃豆鼓有什么好处
蜂蜜炖雪梨的做法微商起步技巧新手刚做微商代理如何找客源摔了个底朝天,我才发现生活中有这么多的裸奔笪桥有百岁老人为予指海岸先生出手9亿多!又有实力公司进军丽水主城!和现在3万的房价对比鲜我的爸爸男篮欧锦赛给中国篮球开了一张新方子,但要治本还得是老方子《草房子》第六章主要内容是什么概括这回,怂了。0差评的4部仙侠剧,琉璃不算啥,最后一部才是百看不厌!宝马集团韦博凡到2023年将推出12款纯电动车,占中国总销量星座与血型分析喜欢管老婆的星座男TOP5

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找菏泽德阳山西湖州宝鸡上海茂名内江三亚信阳长春北海西安安徽黄石烟台沧州湛江肇庆鹤壁六安韶关成都钦州