在CentOS 7上,使用MongoDB进行分片处理

我用三台机器物理上搭建了一个MongoDB集群,组合了分片和副本集。

每个节点的IP地址和端口的示例

IP地址

ノード名 db1 db2 db3 IPアドレス 192.168.0.11 192.168.0.12 192.168.0.13

每个服务使用的端口

ノード名 db1 db2 db3 config 27018 27018 27018 mongos 27017 27017 27017 shard1 27021 27021 27021* shard2 27022* 27022 27022 shard3 27023 27023* 27023
    レプリカセットのshard(x)の後ろに*があるのはArbiter(実データは持たずプライマリノードの選挙権だけを持つ)の意味
    各ノードではconfig/shard1/shard2/shard3の4つのmongodプロセスとmongosプロセスが1つ動いてることになる
    クライアントアプリを各ノードのローカルに配布した場合、mongodb://localhost:27017/your_database で接続できる
    configサーバのレプリカセットにArbiterは存在できない

三台设定相同太麻烦了。

使用类似Ansible这样的自动化工具,可以轻松实现云服务的自动化操作,比如复制磁盘或虚拟机等。我也使用了我在参加某个活动时获得的Sakura Cloud的免费额度来进行操作。

操作系统的设置

安装MongoDB

请参考以下内容(自言自语)

/etc/hosts的配置

为了避免在节点不可用时出现困难,可以在hosts文件中添加名称引用的方式来解析IP地址,这样就可以避免直接输入IP地址的问题。

192.168.0.11 db1
192.168.0.12 db2
192.168.0.13 db3

防火墙的设置

为了使每个节点能够互相连接,我们将开放端口。
由于这台机器在交换机下面直接连接到互联网,所以配置非常松散。

firewall-cmd --permanent  --zone=public --add-port=27017/tcp
firewall-cmd --permanent  --zone=public --add-port=27018/tcp
firewall-cmd --permanent  --zone=public --add-port=27021/tcp
firewall-cmd --permanent  --zone=public --add-port=27022/tcp
firewall-cmd --permanent  --zone=public --add-port=27023/tcp
firewall-cmd --reload

创建用于数据领域的副本集。

创建数据目录

请将每个分片用到的数据库目录挖掘到一个与默认位置稍有不同的地方,
并将执行该进程的用户 mongod 设置为所有权者。

mkdir /data
mkdir /data/log
mkdir /data/mongoc
mkdir /data/shard1
mkdir /data/shard2
mkdir /data/shard3

chown mongod:mongod /data/log
chown mongod:mongod /data/mongoc
chown mongod:mongod /data/shard1
chown mongod:mongod /data/shard2
chown mongod:mongod /data/shard3

创建PID文件存放处

如果已经存在,就不需要了。

mkdir /var/run/mongodb
chown mongod:mongod /var/run/mongodb

数据区域的配置文件

既然我们有MongoDB 3.2,我们将使用WiredTiger进行构建。
一旦创建一个,以后基本上只需复制粘贴即可。
需要根据服务器规格调整各个参数(尤其是cacheSizeGB)。

# shard1.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/log/shard1.log
  logRotate: rename

# Where and how to store data.
storage:
  dbPath: "/data/shard1"
  engine: wiredTiger
  directoryPerDB: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
      statisticsLogDelaySecs: 0
    collectionConfig:
      blockCompressor: "snappy"
    indexConfig:
      prefixCompression: true
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/shard1.pid  # location of pidfile

# network interfaces
net:
  port: 27021

#security:

#operationProfiling:

replication:
   replSetName: "shard1"

sharding:
  clusterRole: "shardsvr"

## Enterprise-Only Options

#auditLog:

#snmp:
# shard2.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/log/shard2.log
  logRotate: rename

# Where and how to store data.
storage:
  dbPath: "/data/shard2"
  engine: wiredTiger
  directoryPerDB: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
      statisticsLogDelaySecs: 0
    collectionConfig:
      blockCompressor: "snappy"
    indexConfig:
      prefixCompression: true
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/shard2.pid  # location of pidfile

# network interfaces
net:
  port: 27022

#security:

#operationProfiling:

replication:
   replSetName: "shard2"

sharding:
  clusterRole: "shardsvr"

## Enterprise-Only Options

#auditLog:

#snmp:
# shard3.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/log/shard3.log
  logRotate: rename

# Where and how to store data.
storage:
  dbPath: "/data/shard3"
  engine: wiredTiger
  directoryPerDB: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
      statisticsLogDelaySecs: 0
    collectionConfig:
      blockCompressor: "snappy"
    indexConfig:
      prefixCompression: true
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/shard3.pid  # location of pidfile

# network interfaces
net:
  port: 27023

#security:

#operationProfiling:

replication:
   replSetName: "shard3"

sharding:
  clusterRole: "shardsvr"

## Enterprise-Only Options

#auditLog:

#snmp:

systemd的配置设置

当您通过yum在CentOS7上进行安装时,似乎需要通过/etc/init.d/*脚本进行处理。但是,根据CentOS7和systemd的惯例,我们将尝试定义一个systemd服务。

也许创建一个脚本并复制粘贴可能是最快的方式,但将其脚本化可能是最方便的方式。

[Unit]
Description=High-performance, schema-free document-oriented database

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=--quiet -f /etc/shard1.conf"
ExecStart=/usr/bin/mongod $OPTIONS
PIDFile=/var/run/mongodb/shard1.pid

[Install]
WantedBy=multi-user.target
[Unit]
Description=High-performance, schema-free document-oriented database

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=--quiet -f /etc/shard2.conf"
ExecStart=/usr/bin/mongod $OPTIONS
PIDFile=/var/run/mongodb/shard2.pid

[Install]
WantedBy=multi-user.target
[Unit]
Description=High-performance, schema-free document-oriented database

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=--quiet -f /etc/shard3.conf"
ExecStart=/usr/bin/mongod $OPTIONS
PIDFile=/var/run/mongodb/shard3.pid

[Install]
WantedBy=multi-user.target

当设置完成后

systemctl daemon-reload

更新设置文件并启动程序。

systemctl start shard1.service
systemctl start shard2.service
systemctl start shard3.service

数据区域的副本集

在MongoDB上配置每个Replica Set。

mongo db1:27021

shard1 > config = {
_id: 'shard1',
members: [
  {_id: 0, host: 'db1:27021'},
  {_id: 1, host: 'db2:27021'},
  {_id: 2, host: 'db3:27021', arbiterOnly: true}
]};

shard1 > rs.initiate(config)
mongo db2:27022

shard2 > config = {
_id: 'shard2',
members: [
  {_id: 0, host: 'db2:27022'},
  {_id: 1, host: 'db3:27022'},
  {_id: 2, host: 'db1:27022', arbiterOnly: true}
]};

shard2 > rs.initiate(config)
mongo db3:27023

shard3 > config = {
_id: 'shard3',
members: [
  {_id: 0, host: 'db3:27023'},
  {_id: 1, host: 'db1:27023'},
  {_id: 2, host: 'db2:27023', arbiterOnly: true}
]};

shard3 > rs.initiate(config)

数据存储现在有三个分区,每个分区都由一个主磁盘、两个辅助磁盘和一个仲裁节点组成。

配置服务器的设置

创建用于配置服务器的配置文件。

# mongoc.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/log/mongoc.log

# Where and how to store data.
storage:
  dbPath: /data/mongoc
  engine: wiredTiger
  directoryPerDB: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
      statisticsLogDelaySecs: 0
    collectionConfig:
      blockCompressor: "snappy"
    indexConfig:
      prefixCompression: true
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/mongoc.pid  # location of pidfile

# network interfaces
net:
  port: 27018

#security:

#operationProfiling:

replication:
   oplogSizeMB: 64
   replSetName: mongoc

sharding:
  clusterRole: configsvr

## Enterprise-Only Options

#auditLog:

#snmp:

写下服务设置

[Unit]
Description=High-performance, schema-free document-oriented database

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=--quiet -f /etc/mongoc.conf"
ExecStart=/usr/bin/mongod $OPTIONS
PIDFile=/var/run/mongodb/mongoc.pid

[Install]
WantedBy=multi-user.target

让systemd识别并启动进程

systemctl daemon-reload
systemctl start mongoc.service

下一个步骤是组建复制品套装。

mongo db1:27018

mongoc > config = {
_id: 'mongoc',
configsvr: true,
members: [
  {_id: 0, host: 'db1:27018'},
  {_id: 1, host: 'db2:27018'},
  {_id: 2, host: 'db3:27018'}
]};

mongoc > rs.initiate(config)

配置服务器: true 这一设置是关键所在。
我忘记了这个,导致卡了快一个小时。

路由器(mongos)

基本操作步骤相同,只是进程的执行文件名由mongod变为mongos,而mongos本身是一个不具备实际数据存储功能的进程,因此不需要设置存储配置。对应的配置文件差异是指定配置数据库(configDB)上的副本集来进行设置。

# mongos.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/log/mongos.log

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/mongos.pid  # location of pidfile

# network interfaces
net:
  port: 27017

#security:

#operationProfiling:

replication:
  localPingThresholdMs: 15

sharding:
  autoSplit: true
  configDB: mongoc/db1:27018,db2:27018,db3:27018

## Enterprise-Only Options

#auditLog:

#snmp:
[Unit]
Description=High-performance, schema-free document-oriented database

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=--quiet -f /etc/mongos.conf"
ExecStart=/usr/bin/mongos $OPTIONS
PIDFile=/var/run/mongodb/mongos.pid

[Install]
WantedBy=multi-user.target

然后开始运行

systemctl daemon-reload
systemctl start mongos.service

如果没有错误,那么配置就算完成了。

将数据实际加载到分片环境中

使用某个终端连接到Mongos。
如果使用这个例子进行设置的话,可以从shell中进行连接。

mongo

应该只是通过这个连接

mongos>

如果是这样的话,那就是正确答案。

将数据库教导至分片环境中。

mongos> sh.enableSharding('dbname')

在这之上,指定一个集合并进行分片。

请指定一个确定哪个分片将存储的键。请提前创建索引。

mongos> sh.shardCollection('collection-name', { someIndex : 1 })

如果能够支持自动启动的话

systemctl enable shard1.service
systemctl enable shard2.service
systemctl enable shard3.service
systemctl enable mongoc.service
systemctl enable mongos.service

bannerAds