最新消息:

MongoDB的分片shard

IT技术 ipcpu 3230浏览

MongoDB的分片shard.md

一、分片概述

在MongoDB中,分片集群(sharded cluster)是一种水平扩展数据库系统性能的方法,能够将数据集分布式存储在不同的分片(shard)上,每个分片只保存数据集的一部分,MongoDB保证各个分片之间不会有重复的数据,所有分片保存的数据之和就是完整的数据集。分片集群将数据集分布式存储,能够将负载分摊到多个分片上,每个分片只负责读写一部分数据,充分利用了各个shard的系统资源,提高数据库系统的吞吐量。

从图中可以看到有四个组件:mongos、config server、shard、replica set。

mongos,数据库集群请求的入口,所有的请求都通过mongos进行协调,不需要在应用程序添加一个路由选择器,mongos自己就是一个请求分发中心,它负责把对应的数据请求请求转发到对应的shard服务器上。在生产环境通常有多mongos作为请求的入口,防止其中一个挂掉所有的mongodb请求都没有办法操作。

config server,顾名思义为配置服务器,存储所有数据库元信息(路由、分片)的配置。mongos本身没有物理存储分片服务器和数据路由信息,只是缓存在内存里,配置服务器则实际存储这些数据。mongos第一次启动或者关掉重启就会从 config server 加载配置信息,以后如果配置服务器信息变化会通知到所有的 mongos 更新自己的状态,这样 mongos 就能继续准确路由。在生产环境通常有多个config server 配置配置成副本集,防止数据丢失!

shard,分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程。将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载。基本思想就是将集合切成小块,这些块分散到若干片里,每个片只负责总数据的一部分,最后通过一个均衡器来对各个分片进行均衡(数据迁移)。

replica set,中文翻译副本集,其实就是shard的备份,防止shard挂掉之后数据丢失。复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性。

二、分片环境的部署

准备三台服务器:192.168.1.101、192.168.1.102、192.168.1.103,规划如下,

192.168.1.101 192.168.1.102 192.168.1.103
mongos mongos mongos
config server config server config server
shard1 主节点 shard1 副节点 shard1 副节点
shard2 副节点 shard2 主节点 shard2 副节点
shard3 副节点 shard3 副节点 shard3 主节点

端口分配

mongos:27021
config:21020
shard1:27017
shard2:27018
shard3:27019

副本集的部署,我们上篇文章已经介绍过,这里不再详细讨论,我们需要在机器上部署shard1、shard2、shard3 三个副本集,并且将PRIMARY节点分散到3台机器上。

配置文件如下:

#start shell: numactl --interleave=all /usr/bin/mongod -f /etc/mongodb/shard1.conf --journal
systemLog:
 destination: file
 path: "/data/logs/mongodb/sahrd1.log"
 quiet: true
 logAppend: true
 timeStampFormat: iso8601-utc
storage:
 wiredTiger:
  engineConfig:
   cacheSizeGB: 6
 dbPath: "/data/mongodb/shard1"
 directoryPerDB: true
 indexBuildRetry: false
# quota:
# enforced: false
# maxFilesPerDB: 8
 syncPeriodSecs: 60
# repairPath: "/var/lib/mongo/_tmp"
 journal:
  enabled:true
# debugFlags: 1
# commitIntervalMs: 100
processManagement:
 fork: true
 pidFilePath: "/data/run/mongodb/shard1.pid"
net:
# bindIp: 127.0.0.1
 port: 27017
# http:
# enabled: true
# RESTInterfaceEnabled: false
# ssl:
# mode: "requireSSL"
# PEMKeyFile: "/etc/ssl/mongodb.pem"
operationProfiling:
 slowOpThresholdMs: 100
 mode: "slowOp"
#security:
# keyFile: "/var/lib/mongo/mongodb-keyfile"
# clusterAuthMode: "keyFile"
# authorization: "disabled"
replication:
 oplogSizeMB: 1024
 replSetName: "shard1"
 secondaryIndexPrefetch: "all"
sharding:
 clusterRole: shardsvr

然后按照上面的例子创建configserver的副本集,配置文件基本类似,注意修改存储路径、端口信息。
最后的clusterRole配置为clusterRole: configsvr 。

接下来,我们来创建mongos,配置文件如下

systemLog:
 destination: file
 path: "/data/logs/mongodb/mongos/mongos.log"
 logAppend: true
processManagement:
  fork: true
  pidFilePath: "/data/run/mongodb/mongos.pid"
net:
 port: 27021
# bindIp: 127.0.0.1
sharding:
 configDB: configsvr/192.168.1.101:27020,192.168.1.102:27020,192.168.1.103:27020

因为mongos分片配置信息是存储在configserver中的,所以登陆任意一台mongos即可,mongo --port 27021,进行操作:

#使用admin数据库
use admin
#串联路由服务器与分配副本集
sh.addShard("shard1/192.168.1.101:27017,192.168.1.102:27017,192.168.1.103:27017")
sh.addShard("shard2/192.168.1.101:27018,192.168.1.102:27018,192.168.1.103:27018")
sh.addShard("shard3/192.168.1.101:27019,192.168.1.102:27019,192.168.1.103:27019")
#查看集群状态
sh.status()

三、测试分片效果

登陆mongos,mongo --port 27021,测试分片效果

#指定要开启分片的数据库
db.runCommand( { enablesharding :"testdb"});
或者
sh.enableSharding("testdb")

#使用哈希片键对集合分片
sh.shardCollection( "testdb.billing", { id: "hashed" } )

#插入测试数据
use testdb
for(var i=0; i<1000; i++) db.billing.insert({id:i*1597,uid:i}); 
db.billing.find()
db.billing.find().count();

#查看数据分片情况
db.billing.stats()

注意:好多教程使用的分片规则不是哈希分片,最终可能数据分布不是很明显。

四、分片规则

MongoDB中数据的分片是以集合为基本单位的,集合中的数据通过片键(Shard key)被分成多部分。其实片键就是在集合中选一个键,用该键的值作为数据拆分的依据。所以一个好的片键对分片至关重要。片键必须是一个索引,通过sh.shardCollection加会自动创建索引(前提是此集合不存在的情况下)。一个自增的片键对写入和数据均匀分布就不是很好,因为自增的片键总会在一个分片上写入,后续达到某个阀值可能会写到别的分片。但是按照片键查询会非常高效。随机片键对数据的均匀分布效果很好。注意尽量避免在多个分片上进行查询。在所有分片上查询,mongos会对结果进行归并排序。

mongos部署时,需要根据业务场景选择合适的分片键(shard key)以决定mongos如何进行数据切分后存储在对应chunk(chunk是mongos数据存储的最小单元,默认是64M)。常见的分片规则有三种:HASH分片、RANGE分片及ZONE分片。

4.1. 哈希分片(Hashed Sharding)

hash分片使用单字段的hash函数作为分片键跨分片集群拆分数据。

4.2. RANGEED分片(Ranged Sharding)

range分片依据分片规则将涉及到的数据划分成连续范围的chunk。

4.3. ZONES分片(Zones in Sharded Clusters)

自定义区域切片。通过对分片键的特定范围进行标记,并将这些标记与shard关联,实现数据的定向存储。
数据拆分如图:

参考资料

https://zhuanlan.zhihu.com/p/29530029
https://www.cnblogs.com/ljhdo/p/4886087.html
http://blog.fens.me/mongodb-shard/
http://www.ityouknow.com/mongodb/2017/08/05/mongodb-cluster-setup.html

转载请注明:IPCPU-网络之路 » MongoDB的分片shard