分片策略 哈希&范围演示|学习笔记

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: 快速学习分片策略 哈希&范围演示

开发者学堂课程【MongoDB精讲课程(下)分片策略 哈希&范围演示】学习笔记与课程紧密联系,让用户快速学习知识

课程地址https://developer.aliyun.com/learning/course/727/detail/12987


分片策略 哈希&范围演示

 

内容介绍:

一、哈希&范围

二、使用建议

 

一、哈希&范围

分片规则有两个策略,一个是哈希策略

对于基于哈希的分片MongoDB计算一个字段的哈希值,并用这个哈希值来创建数据块。

在使用基于哈希分片的系统中,拥有“相近片健的文档 很可能不会存储在同一个数据块中,因比数据的分离性更好些。

使用nickname作为片键,根据其值的哈希值进行数据分片。

mcngos>sh.shardco7lection("articledb.comment,{"nickname":"hashed"})

{

"collectionsharded" : "articledb.conment",

“co1lectionUUID":UUID(ddea6ed8-ee61-4693-bd16-196acc3a45e8")

"ok":1.

"operationTime":Timestamp(1564612840,28)

"Sclustertime":[

"custertime":Timestamp(1564612840,28),

"signature":{

"hash"":BinDataCO"AAAAAAAAAAAAAAAAAAAAAAAAAAA-")。

"keyId":NumberLong(0)

}

再添加一个范围策略,他添加的规则是一样的,前面是库,后面的集合进行分片,分片的规则通过每个字段。后边的值跟之前建立的索引很像,写1或者-1都可以。

分片规则:范围策略

对于基于范围的分片,MongoDB 按照片键的范国把数据分成不同部分,假设有一个数字的片键:想象一个从负无穷到正无穷的直线每一个片键的值都在直线上画了一个点MongoDB把这条百线划分为更短的不重鲁的片段,并称之为数据块,每个数据块包含了片键在一定范围内的数据。

在使用片键做范围刘分的系统中拥有相近片键的文档很可能存储在同一个数据块中,因此也会存储在同一个分片中。

如使用作者年龄字段作为片键,按照点赞数的值进行分片:

mongos> sh.shardco77ection("articledb.author",{"age":1})

{

"collectionsharded":"articledb.author".

"collectionUUID”:UUID9a47bdaa-213a-4039-9c18-e70bfc369df7"),

"ok”:1,

"operationTime":Timestamp(1567512803,13):

"$clusterTime”:{

"clusterTime":Timestamp(1567512803,13),

"signature" :{

"hash":BinData(0."eE90T5yE5sL1Tyr7+3U8GRY5+50=")

"keyId":NumberLong(6732061237309341726")

}

}

加的时候注意,加第一个哈希策略的时候用的是 comment 集合,加范围策略的时候用的是 author,因为 MongoDB 有一个特点,他只能通过一个字段给某一个集合分片,不可以comment既按照哈希策略又按照范围策略,只能二选一。哈希策略可能通过一些哈希值已经固定分了四片,但是范围策略并不会先分,他会通过插入数据的时候自动来分,它默认先分到myshardrs02,然后根据数据大小来自动的进行分片。哈希值有一个上限,有一个最小值,有一个最大值,他有比较确定的数值,但是他不知道默认age是多大,所以先分到myshardrs02来进行一个范围分配。

范围策略

acticledh.author

shard kay: i"age":1 )

unique:false

balancing: true

chunke:

mysharces02      1

(“age”:“SminKey”:1} } -->> : "age”:{ “*SmaxKey’”;1 } } on : myshardre02 Timestamp(1, 0)

哈希策略

articledb.comment

shard key: {"nickname":"hashed" }

unique: false

balancing: true

chunks:

myshardrs01   2

myshardrs02   2

{"nickname”:{"$minKey":1}}-->> {"nickname”:NumberLong("-4611686018427387902")} on : myshardrs01 Timestamp(1,0)

{"nickname”:NumberLong("-4611686018427387902")} -->> {"nickname”: NumberL song(0)} on : myshardrs01 Timestamp(1,1)

("nickname”:NumberLona(0)}-->> {"nickname”:NumberLona(4611686018427387902")} on :myshardrs02 Timestamp(1,2)

接下来向两个集合里面加一些数据,看一下是怎么分类的。

先开两个客户端,Show dbs,数据同步时,articledb中存了多些,哪有数据存在分片1还是分片2。

image.png

再开一个客户端连接分片2,

/usr/local/mongodb/bin/mongo --port 27318

开出来两个分片1和2,分片后插入数据测试

测试一(哈希规则):登录mongs后,向comment循环插入1000条数据做测试:

mongos> use articedb

switched to db articledb

mongos>for(vari=1;i<=1000;i++){db.comment.insert({_id:i+"",nickname:"BoBo"+i})]

writeresult({"nInserted":1})

mongos> db.comment.count)

1000

提示:js的语法,因为mongo的shell是一个JavaScript的shell

注意:从路由上插入的数据,必须包含片键,否则无法插入。

mongos> db

articledb

mongos>for(vari=1;i<=1000;i++){db.comment.insert({ id:i+"",nickname:"BoBo"+i})}

WriteResult({ "nInserted":1 })

mongos>

插入数据成功

mongos> show collections

author

comnent

mongos>

这个时候comnent 已经出来了

刚刚的一千条数据被分别存储到分片1和分片2里面,这个时候就可以看到分片1里面存储了507条数据,计算一下分片二就存储了493条数据。

分片2计算执行过程

myshardrs02:PRIMARY> db test

myshardrs02:PRIMARY> use articledb switched to db articledb

myshardrs02:PRIMARY> db.comment.count()

493

myshardrs02:PRIMARY>

其实这里也是有一定的随机性的,根据哈希特性,数值越大分布的越均匀。

范围策略

测试二(范围规则):登录mongs后,向comment循环播人1000条数据做测试:

mongos> use articledb

switched to db articledb

mongos> for(var i=1;i<=2000;i++)

{db.author.save({"name”:"BOBОBОBCBCBОBОBОBОBОBОBОBОBОBОBОBОBОBCBCBОBОBОBОBОBOBОBОBОBОBOBO BCBOBoBo"+i,"age":NumberInt(i%120)})} writeresult({"ninserted":1})

Mongos>db.comnent.count()

20000

插入成功后,仍然要分别查看两个分片副本集的数据情况。 

分片效果:

articledb.author

shard key:{"age":1}

unique:false

balancing:true

chunks:

myshardrs01  2

myshardrs02  1

{"age":{ "$minkey" : 1 } } -->> { "age':} on : myshardrs02

Timestamp(2,0)

{ "age":0 } -->> {"age":112 } cn : myshardrs01 Timestamp(2,

1)

{ "age": 112 } -->> { "age":{"Sraxkey':1 } } on :

myshardrs01 Timestamp(1.3)

提示:

如果查看状态发现没有分片,则可能是由于以下原因造成了:

1)系统繁忙,正在分片中。

2)数据块(chunk)没有填满,默认的范围规则只给分配到了分片2,

默认的数据块尺寸(chunksize)是64M,填满后才会考虑向其他片的数据块地充数据,因此,为了测试,可以将其改小,这里改为1M,操作如下:

use config

db.settings.save({_id:"chunksize",value: 1})

测试完改回来:

db.settings.save({_id:"chunksize", value: 64 } )

注意:要先改小,再设置分片。为了测试,可以先测除集合,重新建立集合的分片策略,再插入数据测试即可。如果数据块够大是可以不考虑分片的。

 

二、使用建议

当数据不太确定的时候,又想让他随机分片,但是又不确定范围是多少,这里就建议用哈希规则。

如果范围比较多,每次查询的时候有明确目的,使用范围规则的效率是比较高的。

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
7月前
|
存储 NoSQL Redis
详解布隆过滤器的原理、使用场景和注意事项
详解布隆过滤器的原理、使用场景和注意事项
264 0
|
8月前
|
存储 缓存 NoSQL
软件体系结构 - 数据分片(1)哈希分片
【4月更文挑战第20天】软件体系结构 - 数据分片(1)哈希分片
228 8
|
8月前
一道题学会如何使用哈希表
一道题学会如何使用哈希表
|
8月前
|
存储 人工智能
哈希表基础(含代码演示)
哈希表基础(含代码演示)
66 0
|
8月前
|
存储 安全
哈希表概述
哈希表概述
|
算法
29MyCat - 分片规则(固定分片hash算法)
29MyCat - 分片规则(固定分片hash算法)
59 0
|
数据库 索引
简述创建索引的注意事项
创建索引是提高数据库查询性能的重要手段之一,合理地创建索引可以加快查询速度,提升数据库的整体性能。以下是创建索引时需要注意的几个重要事项:
300 0
|
存储 缓存 算法
【C++进阶】九、哈希表
目录 一、哈希概念 二、哈希冲突 三、哈希函数 四、哈希冲突解决 4.1 闭散列(开放定址法) 4.1.1 线性探测 4.1.2 二次探测 4.1.3 研究表明 五、哈希表的闭散列实现 5.1 闭散列哈希表的结构 5.2 闭散列的插入 5.2 闭散列的查找 5.3 闭散列的查找 5.4 哈希表取模问题 5.5 string类型无法取模问题 5.6 完整代码 四、哈希冲突解决 4.2 开散列(链地址法、哈希桶) 六、哈希表的开散列实现(哈希桶) 6.1 哈希桶的结构 6.2 哈希桶的插入 6.3 哈希桶的查找 6.4 哈希桶的删除 6.5 完整代码
132 0
【C++进阶】九、哈希表
|
算法 中间件 关系型数据库
MyCat - 分片 - 分片规则 - 字符串 hash 解析算法 | 学习笔记
快速学习 MyCat - 分片 - 分片规则 - 字符串 hash 解析算法
MyCat - 分片 - 分片规则 - 字符串 hash 解析算法 | 学习笔记
|
存储 算法 中间件
MyCat - 分片 - 分片规则 - 固定分片 hash 算法 | 学习笔记
快速学习 MyCat - 分片 - 分片规则 - 固定分片 hash 算法
MyCat - 分片 - 分片规则 - 固定分片 hash 算法 | 学习笔记