mongodbでシャーディングのラズベリーパイ包み

シャーディングで行うこと

  • configサーバーの準備
  • mongosのセットアップ
  • 5
  • シャード準備
  • mongosからシャード追加

環境

raspberry pi 3b + を4台使用します。
1台目:mongos専用
2台目:configsvr1とshard1
3台目:configsvr2とshard2
4台目:configsvr3とshard3

configsvrとシャードは兼用させます。
configsvrは軽量な為、兼用させても問題ないようです。

configsvr1とシャード1の準備

ラズパイ2台目(192.168.100.20)にログインします。
下記を実行します。

sudo mkdir -p /data/configdb1
sudo mongod --configsvr --dbpath /data/configdb1 --port 27031 --logpath /data/configdb1/log -fork
sudo mkdir /data/shard1
sudo mongod --port 27021 --dbpath=/data/shard1 --logpath /data/configdb1/shard1.log -fork

configsvr2とシャード2の準備

ラズパイ3台目(192.168.100.21)にログインします。
下記を実行します。

sudo mkdir -p /data/configdb2
sudo mongod --configsvr --dbpath /data/configdb2 --port 27032 --logpath /data/configdb2/log -fork
sudo mkdir /data/shard2
sudo mongod --port 27022 --dbpath=/data/shard2 --logpath /data/configdb2/shard2.log -fork

configsvr3とシャード3の準備

ラズパイ4台目(192.168.100.22)にログインします。
下記を実行します。

sudo mkdir -p /data/configdb3
sudo mongod --configsvr --dbpath /data/configdb3 --port 27033 --logpath /data/configdb3/log -fork
sudo mkdir /data/shard3
sudo mongod --port 27023 --dbpath=/data/shard3 --logpath /data/configdb3/shard3.log -fork

mongosの準備

configsvrを指定してmongosを起動します。

mongos --configdb 192.168.100.20:27031,192.168.100.21:27032,192.168.100.22:27033

mongosからシャードを追加します。

mongo
> use admin
> db.runCommand({"addShard":"192.168.100.20:27021"})
> db.runCommand({"addShard":"192.168.100.21:27022"})
> db.runCommand({"addShard":"192.168.100.22:27023"})

試しにデータを追加したりします。

> db.printShardingStatus()
> dv.test.inserrt({cateory:"A",name:"aaa", age: 22 })
> db.test.find()

sharding

mongos> db.runCommand({enablesharding:"test"});
mongos> sh.shardCollection("test.stats_a",{"id":1})
mongos> for ( var i=1; i<=30000;i++){db.stats_a.insert({id:i})}

各シャードにアクセスして分散されていることを確認します。

mongo 192.168.100.20:27021
> db.stats_a.count()
23026

mongo 192.168.100.21:27022
> db.stats_a.count()
0

mongo 192.168.100.22:27023
> db.stats_a.count()
6974

mongoが起動できない場合

ps aux | grep mongo
sudo kill -9 "mongodb process ID"

pymongoによるmongodbの操作

shard設定を有効にするには下記の操作を行います(シェルで言うsh.enableShardingに相当します)。

client = pymongo.MongoClient()
client.admin.command('enableSharding', 'dbname')

さらにコレクションに足して下記の操作をします(シェルで言うsh.shardCollectionに相当します)。

client.admin.command('shardCollection', 'dbname.collectionname', key={'shardkey': 1})

pymongo

ログインするには下記のようにします。

>>> from pymongo import MongoClient
>>> import urllib.parse
>>> username = urllib.parse.quote_plus('user')
>>> username
'user'
>>> password = urllib.parse.quote_plus('pass/word')
>>> password
'pass%2Fword'
>>> MongoClient('mongodb://%s:%s@127.0.0.1' % (username, password))
...

host1/host2/host3はmongosサーバーを指定します。
こうすることでロードバランサーとして働きます。

>>> client = MongoClient('mongodb://host1,host2,host3')

pymongoはlocalThresholdMS内のmongosサーバーに均等に分配します。
localThresholdMSのデフォルト値は15msです。
このため例えば下記のようなレスポンス時間のmongosがあるとします。
するとhost1が最もレスポンスが早いため選択されるか、
host2が最も早いレイテンシ(host1)の15ms以内のため選択されます。
host3はhost1より20msも遅いため選択されません。

host1: 20 ms
host2: 35 ms
host3: 40 ms


DBにアクセスするには下記のようにします

db = client['test-database']

コレクションにアクセスするには下記のようにします

collection = db['test-collection']

下記のようなデータを追加することを考えます。

import datetime
post = {"username": "j04328",
"d1": 30,
"tags": ["mongodb", "python", "pymongo"],
"date": datetime.datetime.utcnow()}

下記のようにするとデータを追加できます。

result1 = collection.insert_one(post)

複数同時に追加したい場合には下記のようにします。

result2 = collection.insert_many(posts)

すべてのデータを取ってくるには下記のようにします。

for data in collection.find():
print data