《Designing Data-Intensive Applications》学习笔记 Chapter6

sharding是数据系统中最常见的措施,在分布式,去中心化的今天,业务数据不断增长,单机必然无法容纳所有的数据,因此,分片是必然的选择。本质上,每一个分片其实都是一个数据库的数据,尽管很多数据库支持的搜索,屏蔽了底层多个分片结合的处理


image.png

这是典型的分片和副本同时使用数据存储

1.1 分片策略

  • partition by key range
    优点:方便操作,范围查找比较容易
    缺点:可能会不太平均,造成负载不均衡
  • partition by hash key
    通过hash function去进行离散,注意,不同的hash算法会导致hash出不同的值,在同一个应用中,需要保证使用的离散函数是一样的
    缺点:range query 变得很麻烦,很多存储甚至都不支持

1.2 不均衡负载和热点数据

这个目前都是由应用进行处理,如对于热点数据,提升副本数量,对于不均衡负载,可以在key上追加信息,以达到hash后随机的问题

1.3 分片和第二索引

第二索引显然会增加复杂度,许多 key-value stores (such as HBase and Volde‐
mort) 是不支持第二索引的,但像solar,elasticSearch等都对此进行了支持,这也是它们的主要用途
这里主要有两种思路去支持第二索引分片

By document

image.png

每个分片,维护自己的第二索引,也叫做local index,当你需要增删改文档时,只需要更新那个分片里的文档和第二索引。因此当你使用不包含主键的查询时,必然是需要去所有的分片进行查询,再进行合并,也被称作scatter/gather,因为查询过程是并行去所有分片,所以查询的代价是昂贵的。
如果可以,尽量在构建文档时,使得查询在一个分片中进行
MongoDB, Riak , Cassandra , Elasticsearch , SolrCloud , and VoltDB都采用了这个方式

By term

image.png

和by document相比,区别主要在于second index是否是每个partition单独维护,by term选择是维护一个global index,所有的second index可以在任意的分片上
那么相比主流的方案,它的优缺点是什么?
优点:查询非常方便,你的查询条件可以根据字段到指定的分片上去查询,然后直接去对应的分片拿到文档
缺点:使得更新,新增,删除非常麻烦,原来这些操作可以在一个分片上完成,现在对一个文档操作,会需要将对应的第二索引到各个分片上,操作成本高昂,且同步成本高,异步又导致数据可能会更新不一致

1.4 rebalancing partition

数据和请求,从一个节点移到另一个节点的过程,称为 rebalancing
要求
1.再平衡结束后,数据和请求时平衡的
2.再平衡的过程中,可以正常服务
3.再平衡,要尽量是的网络和磁盘IO尽可能小,速度尽可能快

再平衡策略

  • 重新分片
    之前我们说了分片通过hash(key)
    那么v=hash(key)
    0 将一个段中的value放在一个分片中,此外还可以采用hash(key) mod N 的方法,但mod N有一个问题,万一每个节点由问题有问题,N减小或者扩大了,会有太多的数据进行移动,而rebalancing过程中,我们需要移动的数据尽可能小

  • 辅助的解决方法---增加分片数量
    假设10个节点,原来将数据分为10份,现在新增一个节点,重新按range划分后,你会发现所有的整份数据都有要移动的,这个成本太大了。但如果如果你分片为1000,此时,每个节点包含100个数据库分片,就可以用更小维度的分片进行再分配,减小移动的数据量


    image.png

    由于数据移动是一个可能较长的时间段,在移动过程中,仍然由老数据提供服务

  • Dynamic partitioning
    key range–partitioned databases such as HBase and RethinkDB create partitions dynamically
    当一个分片数据增长过大,会自动切分为2分片,当一个分片删除了太多数据,又会进行合并操作成为一个分片
    pre-splitting
    为了避免数据库从0开始灌注数据时,从0开始频繁分片,可以根据经验等设置一个初始预分片数值

手动还是自动进行分片
自动分片很方便,但分片是一个很昂贵的操作,全自动分片可能会导致性能降低,有些数据库会提供分片的参考值,由人工手动决定是否执行

1.5 Request Routing

  • service discovery
    服务发现是各个环节支持自动化扩展所必须的东西,在再平衡中,当分片完成了,你必须知道新的请求究竟要被分配到哪个节点上,这其实也是服务发现的一种,从更高的层面上来说,主要由几种思路


    image.png

    1.随机发到任意节点,由节点判断是自己处理还是再次转发
    2.通过一个路由节点,进行处理,也可以当做是负载均衡
    3.客户端了解分片的规则,直接指定到具体的节点

关于服务发现,可以通过zk等中间件实现,如果不依赖外部的话,就要提供节点间的协议用来共享更新数据

你可能感兴趣的:(《Designing Data-Intensive Applications》学习笔记 Chapter6)