一 前言

大数据的概念已经热了几年了,以后大数据越来越平常。而大数据的存储和处理,必然会用到分布式系统,所以有必要对分布式系统有所了解。在此,想结合自己学习写些文章, 这些文章可能有些无聊,尽量结合些实例来说明下。

大数据虽然不是纯粹说是数据量大,比如还有数据种类多,格式多样等,但是数量大也算是大数据的特点之一了。大数据的首要问题就是如何存下这么大量的数据,单台机器一般情况下因为存储介质小或性能不够等原因,需要将数据保存在不同的机器上。就像一个大蛋糕,需要切成几片一样,大数据也需要切成几份,来保存。这些数据子集总体组成我们整体的大数据内容。

数据分片和数据复制一般结合起来的,数据分片提升了数据新建的速度。数据复制或者叫数据的副本越多,读取性能更好,因为可以同时在不同的副本上进行读取。数据分片之后,每片数据量不太大,也便于备份,建立副本。

数据分片示意图

二 分片算法要求

  • 均衡性 分布式的目的就是用多台机器来分担单台机器难以完成的任务,那么数据在分片的时候,均衡性是我们首要考虑的问题,如果不均衡会严重影响整体的性能。所以我们分片要尽量保持均衡。比如我们有 3 台机器,一万条数据,那么尽量一台保存三千三百条左右比较好。

  • 数据的稳定性 数据稳定性是指当分布式系统中的一台坏了或添加新的一台机器,数据按照我们的分布规则,带来的影响尽量小。

  • 高性能 分区算法是每条数据都需要进行的操作,无论是新建还是查询,均需要进行分区计算,所以性能要尽可能高。

三 常见的分片算法

在介绍之前,先来看下通用的数据分片和路由通用模型,来完成从一条具体的数据映射到具体的物理节点上存储。数据分片是讲根据哪种算法来划分数据子集,而数据路由包括数据到分片,再从数据分片映射到物理节点上。

分片和路由模型

如上图 抽象成二层映射,首先根据数据的 key 做 key 和 shard 的映射,将数据划分到不同的分片上去,这种是一种多对一的关系,即多条数据映射到一个分片上去。第二层映射是分片和物理机器的映射,也是一种多对一的关系。一台物理机器可以包含多个 shard 分片,比如 solr 就可以这样。

  • 「轮询」
    比如在消息含有 key 的情况下,kafka 默认的分区器(这里可以看作是分片器)尽力确保相同的 key 路由到同一个 paratitioner(Java 版本的生产者使用 murmur2 算法计算 key 的哈希值);若没有指定 key 则按照轮询方式确保消息在 topic 的不同 paratitioner 上均匀分配。由于 kafka 算是个消息引擎系统,所以很少做查询可以这样做,一般需要查询的系统很少用轮询方式来分片数据。

  • 「哈希算法」
    哈希算法是非常常见的数据分片方式,数据分片根据 key 映射到不同的分片上去。举个简单的例子,在 Solr 集群中,计算文档归属的 shard 的公式:

Math.abs(id.hashcode() % numShards)

solr 里面使用的 hash 算法是 Murmurhash 算法。这是刚才说的第一层映射 key-shard 的映射。

shard 和 solr 的节点如何映射。solr 在 cloud 模式下,按照开始划分的 shard 数,将0-ffffffff这个数据空间划分 shard 数个,不同的 shard 保存不同范围的数据,可以看看下面的 state.json 配置,注意其中的 range。

"collection1":{"replicationFactor":"1","router":{"name":"compositeId"},"maxShardsPerNode":"1","autoAddReplicas":"false","shards":{"shard1":{"range":"80000000-7fffffff","state":"active","replicas":{"core_node1":{"core":"collection1_shard1_replica1","base_url":"http://ip:8181/solr","node_name":"ip:8181_solr","state":"active","leader":"true"}}}}}}

哈希算法的好处是速度快,比较简单,但是也有坏处,就是刚才说的数据稳定性。比如我们机器从 4 台变更为 5 台后,如果没有特殊处理办法,所有的数据都会发生变动,需要迁移大量数据。

而且哈希算法中各个机器的地位是均等的,不适合于异构类型的机器。

「原因:这种哈希算法,将 key-shard 映射和 shard-machine 映射合二为一了,且以物理节点数作为模,物理节点数和映射紧耦合」

  • 「一致性哈希算法」
    一致性哈希算法将物理节点和数据都映射到一个环上,存储节点可以根据 IP 地址等进行哈希,数据通常通过顺时针方向寻找,来确定数据存储的物理节点。如下图:

一致性哈希算法

上图中,首先我们将节点按照 IP 计算哈希值,映射到哈希空间中去,一般这个空间定义为 0-232-1。一个数据的 hash 值为 8,按照一致性哈希算法,顺时针寻找存储节点,即数据保存到物理节点 N14 上;另外一个数据计算哈希的值为 19,数据保存在物理节点 N20 上。

如何实现算法那?当我们在一个物理节点查询数据的时候,如果值在这个范围则直接返回,如果不在这个物理节点那,那通过此物理节点的后续节点继续寻找。不过这种方法比较低效,一般优化办法,是在每个节点上保存路由表信息,路由表保存距离当前节点 2i的哈希空间距离:20 21 22 .. .2n然后可以通过类似二分查找的速度快速定位到物理节点。

Cassandra 和 Dynamo 很多分布式系统都采用这种算法的变体。可以看出利用这种算法,如果增加一个节点或者删除一个节点,影响的范围有限。

虽然一致性哈希算法提升了数据的稳定性,但是如果又节点挂了,数据迁移到另外的节点上去,导致这个节点的压力过大,挂了,再顺时针寻找下一个节点,将刚才挂掉的 2 个节点的数据再迁移到这个节点上,从而导致这个节点挂掉,就这样导致整个系统的节点都挂掉;另外一致性哈希算法也没有解决异构物理节点的问题,即如果机器的性能不同,采用一致性哈希算法是一样的权重,实际上导致了不均衡问题。

  • 「带负载的一致性哈希算法」类似于一致性哈希算法,但是节点上保存节点存储数量的上限,当数据按照哈希算法应该保存到这个节点的时候,先判断这个节点的数据是否达到了上限,如果此节点的数据已经到底了上限,继续按照顺时针方向寻找。

这样可以解决刚才的节点负载过重而导致的挂掉问题,但是仍然没有解决异构物理节点的问题。HAProxy 就采用带负载的一致性哈希算法来进行数据分片。

  • 「带虚拟节点的一致性哈希算法」
    这种虚拟节点的一致性哈希算法,也比较简单,就是在数据映射到物理节点加一层中间层。即先把数据或分片映射到虚拟节点上,再将虚拟节点映射到物理节点上。这样我们可以根据物理节点的性能情况来配置虚拟节点的个数。比如我们有三台机器 A,B,C,它们的性能比为 1:2:3 ,我们给 A 机器分配 100 个虚拟节点,给 B 机器分配 200 个虚拟节点,给 C 机器分配 300 个虚拟节点。

带虚拟节点的一致性哈希算法优点:

  1. 解决了物理节点的异构性问题,我们可以根据机器的性能不同,而分配不同的虚拟节点数,再将虚拟节点映射到哈希空间环上,数据整体上更均衡。

  2. 当一个物理节点挂了之后,它对应的 N 多个虚拟节点需要移除,这些虚拟节点的数据按照顺时针的方向,找到的物理节点很可能是不同的物理机器,从而不会因为机器挂掉而导致另外一台物理节点压力过大的问题。

memcache 就采用带虚拟节点的哈希一致性算法。

四 其他

这里面稍微说下,数据分区和数据分片,数据分区是从数据存储的维度划分,不同的分区一般位于不同的物理节点上,可以存储相同的数据也可以存储不同的数据。数据分片是从数据本身出发,每个分片是数据集合的一个子集。但是实际上这种划分并没有那么严格。

在 Solr 中,shard 是对应分片,而分区是靠 shard 对应磁盘上一个个 core 来对应的;在 kafka 中,数据分片直接用 partition 来表示,这个即是数据的逻辑分片,也对应了存储分区。

五 诗词欣赏


破阵子·为陈同甫赋壮词以寄之[宋] [辛弃疾]醉里挑灯看剑,梦回吹角连营。
八百里分麾下炙,五十弦翻塞外声。沙场秋点兵。
马作的卢飞快,弓如霹雳弦惊。
了却君王天下事,赢得生前身后名。
可怜白发生!

分布式系统-分片和路由相关推荐

  1. 大数据日知录(一)数据分片与路由

    概念     目前主流的大数据存储与计算系统通常采用横向扩展(Scale Out)的方式支持系统可扩展性,即通过增加机器数目来获得水平扩展能力.对于待存储处理的海量数据,需要通过数据分片(Shard/ ...

  2. Elasticsearch之指定分片、路由查询

    一.分片 都知道一份数据只会在一个分片上出现,当分片数很多的情况,如果要查询某个数据并且已知在某个分片上,那么就可以指定分片查询,避免ES在查询的时候做无用功,效率低! DSL方式 直接在URL上拼接 ...

  3. ElasticSearch数据分片-数据路由

    ElasticSearch(简称ES):是一个基于Lucene构建的开源.分布式.RESTful的全文本搜索引擎:它还是一个分布式实时文档存储,其中每个field均是被索引的数据且可被搜索:也是一个带 ...

  4. 分布式系统用户登录路由

    转载于:https://www.cnblogs.com/wangbin/p/8544496.html

  5. 分库分表之历史表如何选择最佳分片路由规则

    前言 先别急着关闭,我相信这篇文章应该是所有讲分表分库下的人都没有和你们讲过的一种分片模式,外面的文章基本上都是教你如何从零开始分片,现在我将讲解的是如何从1+开始分片 项目地址 github地址 h ...

  6. ShardingSphere 5.2.1 发布|新增系统库、强制分片路由、一致性校验

    Apache ShardingSphere 本周迎来了 5.2.1 版本的发布,该版本历时一个半月,共合并了来自全球的团队和个人累计 614 个 PR,新版本在功能.性能.测试.文档.示例等方面都进行 ...

  7. 分布式系统的冰与火与技术栈

    最近在极客时间看到一个课程叫<左耳听风>,第一反应是叫这个名字,太不突出重点了,能好卖吗.但当了解作者后,发现是我错了.作者好牛比啊.所以要感受下骨灰级程序员的魅力.先从分布式系统入手学习 ...

  8. Redis核心技术-高可靠-集群方案(客户端分片、代理分片、Redis Cluster)

    Redis在3.0版本前只支持单实例模式,虽然Redis的开发者Antirez早在博客上就提出在Redis 3.0版本中加入集群的功能,但3.0版本等到2015年才发布正式版. 各大企业等不急了,在3 ...

  9. 12|引擎分片:Elasticsearch如何实现大数据检索?

    12|引擎分片:Elasticsearch如何实现大数据检索? 你好,我是徐长龙. 上节课我们看到了ELK对日志系统的强大支撑,如果没有它的帮助,我们自己实现分布式链路跟踪其实是十分困难的. 为什么E ...

最新文章

  1. 数据结构课程设计——机票售卖系统(C++)
  2. 推荐一套开源通用后台管理系统(附源码)
  3. 阿里云服务器部署SpringBoot项目(mysql安装、服务部署)
  4. .NETer,如何用.NET Core 3.0武装自己?这样学效率提高10倍!
  5. oracle lms进程 内存,Oracle RAC 内存融合(Cache Fusion)
  6. SQL Server 中截取字符串常用的函数
  7. 正则表达式的一些规则
  8. Unity3D技术之优化图形性能绘制调用批处理浅析
  9. Hive 之 常用函数
  10. Android loader 详解
  11. 软通动力:致力智慧城市与大数据协同发展
  12. 【R语言】GARCH模型的应用
  13. [copypaste]各种渐进表示法
  14. springboot jar包启动 读取resource下的文件
  15. Python运维之 Flask + 宝塔运行小应用
  16. SQL server中函数依赖,完全与部分函数依赖,平凡和非平凡函数依赖
  17. 年薪 170 万阿里 P8 程序员征婚上热搜,程序员婚恋观大曝光!
  18. MKB0805心率血压模块使用方法
  19. Word调查问卷表格统计
  20. 2022-2028全球及中国弹性体行业研究及十四五规划分析报告

热门文章

  1. 支持nfc的android手机型号,哪些手机型号支持刷公交卡 支持nfc功能的手机有哪些汇总...
  2. Java 中 String 字符串可以有多长?65535?
  3. 分布式计算的详细笔记
  4. 【入门到精通】安装与运行PHP脚本语言
  5. Git快速提交Github步骤
  6. 2022年湖北省企业吸纳就业补贴申请条件及具体奖励标准
  7. 计算机不识别u盘咋办,电脑无法识别u盘如何修复,电脑不识别u盘怎么办
  8. 数据结构与算法实验题 9.8 转移炸弹
  9. python绘制常用的概率分布曲线
  10. php网页视频播放插件下载_视频播放插件Video.js