mongodb + node/expressで、スケールアウト/水平スケーラビリティ 分散構成のような例 #mongodb #node #javascript #noSQL

■ 概要:


前のmongodb 、関係となり。インフラ構築が含まれますが。
高速化、性能向上 を検討した例となります。

・mongodb の、シャーディング、レプリケーション は使用しない例となります。
・noSQLでは 水平分散構成が実現しやすく、
 構性能な計算機を増設せずに、スケール向上が可能なようです。
RDBでは結合等の関係で、水平分散構成は難しいようです

■ 環境

mongoDb : 3.6.3
node 14
・npm
mongodb: 3.6.3
express
docker
windows 10 / WSL / ubuntu 18

■ 参考

https://www.slideshare.net/tetsutarowatanabe/mongo-db-32210761

https://ja.wikipedia.org/wiki/NoSQL

■ 構成。複数mongoDbと、collection分散

画像1

・collectionを、複数のmonogoDBに分散しておきます。

・host nameは、hostsファイル等で、参照できるように設定し。
node側から、各mongoDbに接続できるように設定

■ テストでの、mongoDB環境の手順

・ 複数のmongoDBを、テスト用の仮想環境に配置します。
win WSL, dcoker に配置し、port番号を変更して。各mongoDbに接続

・docker / docker-compose.yml ,の例
https://gist.github.com/kuc-arc-f/1e50cb39cf85a0456538d399cd829300

version: '3'
services:
 mongo:
   image: mongo
   command: 
     - mongod
   ports:
     - 27017:27017
   volumes:
     - mongo-data:/data/db

 mongo-data:
   image: busybox

volumes: 
 mongo-data:

・local / WSLは、port番号を、初期から変更

sudo nano /etc/mongodb.conf

port = 27018

で、27018に変更して。起動

・mongoで、初期port以外に接続する場合。--port オプションを指定すと接続可能でした

mongo --port 27018

・上記で、接続は

mongo-1台目 : host=localhot, port = 27018
mongo-2台目 : host=mongo2, port = 27017

db名は、同じにしておきます。

■ テスト

・複数の mongoDBに、接続し。必要な各collection を取得

test5_mongo2.js
https://gist.github.com/kuc-arc-f/089f44a4cf0b950d7068064ab212f986

async function test2(){
   var orders= []
   try{
       // connect localhost
       let client = await MongoClient.connect( "mongodb://localhost:27018" );
       const db = client.db("db1");
       await db.collection("orders").find().toArray().then((docs) => {
           orders = docs
       }).then(() => {
           client.close();
       });        
console.log( "orders.length :", orders.length );
       // connect mongo2
       books = []
       let client_2 = await MongoClient.connect( "mongodb://mongo2:27017" );
       let db_2 = client_2.db("db1");
       await db_2.collection("books").find().toArray().then((docs) => {
           books = docs
       }).then(() => {
           client_2.close();
       });        
       console.log( "books.length :", books.length );
   } catch (err) {
       console.log(err);
   }
}

・ 実行結果

$ node test5_mongo2.js
orders.length : 4
books.length : 3

・web画面等に、必要な配列データなどを。APIから出力するような形を想定
前は、aggregateで、結合事例を。公開しましたが。
今回は、複数のDbから、必要なcollectionを読込/書き込み する形です

■ 参考の、 node/express

■ 取得の例

・分散collectionの取得, リスト画面に出力する配列の生成
Reactで、renderする例です。
routes/api_orders.js


router.get('/index', async function(req, res) {
   try{
       var t0 = performance.now();
       const collection = await LibMongo.get_collection("orders" )
       var page = req.query.page;
       LibPagenate.init();
       var page_info = LibPagenate.get_page_start(page);       
console.log( "page=",  page, page_info );
       var limit = {skip: page_info.start , limit: page_info.limit }
       var docs= await collection.find({} , limit ).sort({created_at: -1}).toArray()
//console.log(docs)
       const collection_2 = await LibMongo.get_collection_mongo2("books" )
       var books = await collection_2.find({}).toArray()
       var order_items = LibOrders.get_order_items(docs , books)
       var t1 = performance.now();
//console.log(order_items)
//console.log("Call to function took= " + (t1 - t0) + " milliseconds.");
       var param = LibPagenate.get_page_items(order_items )
       res.json(param);
   } catch (err) {
       console.log(err);
       res.status(500).send();    
   }   
});

■ 関連のページ

mongodb + node/expressで、join結合のような例
https://note.com/knaka0209/n/n00c1638d3288


...



いいなと思ったら応援しよう!