数据分片
架构
原理
分片片建
从文档中选择一个字段作为分片片建,根据该字段的取值范围,(也可以是该值的哈希范围)划分多个区间,一个分片节点对应一个或多个数据段,根据该字段的取值的不同,存储到不同分片上
- 片建的值或值的哈希值,用来将集合中的文档划分为多个数据段
- 片建必须对应一个索引或索引前缀(组合索引的前缀)
片键的选择
片键一旦选择就无法更改,选择时间要格外谨慎
- 片键值的范围大,,无法满足时可采用组合片键来扩大范围
- 片键值均匀分布,无法满足时可采用组合片键来平衡分布
- 片键值不要单向增大或减小,无法满足时可采用哈希片键
数据段分裂和迁移
当某个数据段所包含的文档过多,容量过大时,此时就会将该数据段分裂成若干更小的数据段(只有新增或更新文档时才可能自动触发),数据的分裂只是通过更新元数据来实现的,不会进行数据层面上的操作
当后台运行的平衡器发现,最多数据段分片和最少数据段分片之间,数据段数量相差过大时,为了集群数据平衡,就会进行数据段迁移,数据层面上的迁移,添加或删除分片节点时也会触发该操作
分片查询
若要请求的数据能根据元数据信息查询到数据所属分片节点,即请求包含分片片键,就将请求转发给该分片节点,分片节点将数据返回给路由节点,路由节点再将数据返回给客户端
若要请求的数据不能根据元数据信息查询到数据所属分片节点,即请求不包含分片片键,就会将请求转发给所有分片节点,路由节点在将分片节点们的返回结果进行汇总,再返回给客户端
实现方式
服务端
- 增加以下配置信息,启动配置节点和分片节点
- 配置节点必须是复制集,而且不能使用投票机
- 分片节点可以是单机节点
sharding:
clusterRole: configsvr
sharding
:数据分片clusterRole
:指定在分片中的角色,可以是configsvr
配置节点、shardsvr
分片节点
- 增加以下配置信息,使用
mongos
启动路由节点,注意:不支持storage
配置项和security
配置项
sharding:
configDB: myset/127.0.0.1:27018,127.0.0.1:27019,127.0.0.1:27020
#配置腹直集名称/配置集中的节点主机IP和端口,多个节点使用逗号分隔
- 使用
mongo
客户端连接到路由节点,执行sh.addShard(URL)
将分片节点加入到集群中,添加后可以使用sh.status()
查看- 单机分片节点
URL
就是IP和端口 - 复制集分片节点
URL
与configDB
配置项的URL
一样:配置腹直集名称/配置集中的节点主机IP和端口,多个节点使用逗号分隔
- 单机分片节点
- 在路由节点上再执行
sh.enableSharding(database)
指定数据库开启分片功能 - 在路由节点上再执行
sh.shardCollection(dbtabaseDotCollection,key,unique)
,添加后可以使用sh.status()
查看dbtabaseDotCollection
:指定集合,使用数据库点集合形式字符串shardKey
:指定集合的片键(必须是索引,集合不存在时会自动创建索引),片键的值可以是hashed
哈希片键、1
顺序片键unique
:是否是唯一索引,默认false
客户端
MongoClientOptions build = new MongoClientOptions.Builder(). //构建配置对象
connectionsPerHost(10). //每个地址对象的最大连接数
connectTimeout(10000). //连接超时时间
socketTimeout(1000). //读写操作超时时间
build(); //构建完毕
ArrayList<ServerAddress> ServerAddresses = new ArrayList<>(); //集群节点列表
ServerAddresses.add(new ServerAddress("127.0.0.1", 27017)); //路由节点1
ServerAddresses.add(new ServerAddress("127.0.0.1", 27018)); //路由节点2
MongoClient mongoClient = new MongoClient(ServerAddresses, build); //根据所有节点地址和连接配置对象创建连对象
MongoClientURI connectionString = new MongoClientURI("mongodb://127.0.0.1:27017,127.0.0.1:27018"); //创建连接URI
MongoClient mongoClient = new MongoClient(connectionString); //根据URI创建连接对象
Comments NOTHING