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

简介: 快速学习分片策略 哈希&范围演示

开发者学堂课程【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 } )

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

 

二、使用建议

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

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

相关文章
|
开发框架 Java Maven
Spring Boot -01- 快速入门篇(详解图文教程)上
Spring Boot -01- 快速入门篇(详解图文教程)
|
2天前
|
数据采集 人工智能 安全
|
12天前
|
云安全 监控 安全
|
3天前
|
自然语言处理 API
万相 Wan2.6 全新升级发布!人人都能当导演的时代来了
通义万相2.6全新升级,支持文生图、图生视频、文生视频,打造电影级创作体验。智能分镜、角色扮演、音画同步,让创意一键成片,大众也能轻松制作高质量短视频。
1025 151
|
3天前
|
编解码 人工智能 机器人
通义万相2.6,模型使用指南
智能分镜 | 多镜头叙事 | 支持15秒视频生成 | 高品质声音生成 | 多人稳定对话
|
17天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
1722 9
|
8天前
|
人工智能 自然语言处理 API
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸
一句话生成拓扑图!next-ai-draw-io 结合 AI 与 Draw.io,通过自然语言秒出架构图,支持私有部署、免费大模型接口,彻底解放生产力,绘图效率直接爆炸。
665 152
|
10天前
|
人工智能 安全 前端开发
AgentScope Java v1.0 发布,让 Java 开发者轻松构建企业级 Agentic 应用
AgentScope 重磅发布 Java 版本,拥抱企业开发主流技术栈。
632 15