让我们尝试一下NoSQL——最快理解MongoDB
首先本文旨在以最快的方式理解NoSQL的MongoDB,并总结了MongoDB的介绍、mongo shell的基本操作以及备份和日志轮换等内容。
非关系型数据库Webサービスで利用されるデータベースとして、NoSQLも大分浸透してきました。
二大巨頭であるMySQLやPostgreSQLの後ろをしっかり走っています。
かつて、2011年頃まではWebサービスのアクセス数上位20サイトのうち、世界では18サイト、国内では19サイトで利用しているRDBMSとして、MySQLが挙げられていてました。(参考記事)
また、PostgreSQLについても、現在も世界中で多く使用されていると思います。
RDBMSがここまで長く使われてきた理由は、汎用的ゆえに、信頼性を要求されるOLTPや複雑な検索に特化したDWH、更新負荷の高いバッチ処理等いかなる局面において求められるパフォーマンスを発揮していたからではないでしょうか。
高速且轻量的MySQL,和功能强大且高度可靠的PostgreSQL,无论是在架构上还是在理念上都存在差异,但它们各自都是优秀的软件。
然而,在需要高速搜索的网络服务中,所需的是简洁性。因此,擅长将简单搜索进行加速的NoSQL技术的崛起是必然的。
以下内容来自维基百科。
NoSQL指的是除了关系数据库管理系统(RDBMS)以外的数据库管理系统的一个大致分类术语,通常被解释为“不仅仅是SQL”。
非关系型数据库的类型
键值数据库 zhí shù jù kù)键值型数据库也被称为键值存储(KVS:Key-Value Store),它以键值对数组(关联数组)的形式来保存数据。其优点在于它的简单性,从而提供了良好的性能。
文档导向数据库 shù jù kù)ドキュメント指向データベースは、1件分のデータを「ドキュメント」としてデータを格納します。また、個々のドキュメントのデータ構造は自由で、データを追加する都度変えることができます。スキーマレスになるので、リレーショナルデータベースとは違って、事前にテーブルの構造を決めておく必要がありません。また、最大の利点は、スケーラビリティを重視していることです。大量のデータを扱うシステムにおいて、リレーショナルデータベースと比べて、比較的簡単にスケールできるような仕組みを持っていることが一般的です。MongoDBは、ドキュメント指向データベースになります。
指向数据库的列将适合列方向操作的数据库称为”列式数据库”。频繁进行列方向操作时,性能会得到优势。
MongoDB概要作为支撑互联网技术的一部分,Ajax和WebAPI已被广泛采用,几乎所有的网站都在使用,并且还有JavaScript、JSON和YAML等相关技术作为补充支持。
昨今、WebAPIでデータ取得する場合は、JSONがデファクトスタンダードだと思います。
しかし、従来のRDBMSでは、階層的なJSONのスキーマ定義をすることは困難であり、WebAPIは仕様変更されることも多く、その度にスキーマを変更するのは大変です。
基於這樣的背景,MongoDB誕生了。
建筑设计
-
RDBMSのようにレコードをテーブルに格納するのではなく、「ドキュメント」と呼ばれる構造的データをJSONライクな形式で表現し、そのドキュメントの集合を「コレクション」として管理する
-
コレクションはスキーマレスなドキュメントで格納され、任意のフィールドを好きなときに追加できる
-
ドキュメントには複雑な階層構造を持たせることもでき、それらの構造に含まれるフィールドを指定したクエリやインデックス生成も簡単な指定によって行える
-
KVSでは苦手なValueを検索の条件としたり、ソート・集計を実現できる
永続性を提供
MongoDBは、以下のようなシステムに適しています。
-
Webサイトの操作データログの蓄積
-
アドホックなフィールドを検索対象とするコンテンツ
ソーシャルゲーム
でも、MongoDBは以下のことができません。
-
NoSQLなので、SQLは使用できない。クエリはJavaScriptで行う
-
RDBMSのように高度な結合操作(joinに相当する2つの関係から1つの関係を返す演算処理)
トランザクション処理(※)
(※)MongoDB 4.0 でマルチドキュメントトランザクションがサポートされました。これにより、RDBMS likeのような一貫性のある処理を行うことができますが、以下の条件が必要です。
-
レプリカセット構成あるいはシャーディング構成
-
Feature Compatibility Version(FCV)4.0以降
WiredTigerストレージエンジン(※)
(※)MongoDB2.6まではストレージエンジンがMMAPv1、MongoDB3.2からWiredTigerがデフォルト
因此,如果需要涉及多个事务的查询,则MongoDB并不适合。
端的にいうと、MongoDBは万全ではありません。
適材適所になるのでシステムに合わせてRDBMSと使い分けが必要です。
基本は、MongoDBは非正規化したドキュメント構造を扱っているので、どうしても分割されてしまうドキュメントに対しての排他処理を行いたい場合に、マルチドキュメントトランザクションを使用すればいいのではないかと考えます。
機能
-
レプリカ
-
レプリケーションを構成することで障害耐性も高め、フェールオーバーが簡単にできる。RDBMSで言うLifeKeeperのような商用ソフトウェアは不要。
-
シャーディングで水平スケーリングが可能
-
スケールアウトが容易に可能になり、RDBMSよりも高速なレスポンスが得られることがある
-
(逆説的に言うと非正規形前提で設計しているので、結合演算が不要な場合はそのパフォーマンスを発揮する)
-
GridFSと呼ばれるプロトコルを使用することで、大きなファイルをデータベースに格納・取得することができる
インメモリ機能により、高速なReadを実現するためにpageと言う単位でデータをメモリに保持している
(※)厳密に言うと、ファイルシステムに格納されているコレクションをmmapしている
(※)メモリ内に無いデータはディスクからロードすることになる、(Page Fault)
そのため、Page FaultはメモリからReadする場合と比較して時間がかかってしまう
其他
共享
DB-Enginesによると、2019年2月の時点でOracle Database、MySQL、Microsoft SQL Server、PostgreSQL等の歴史あるRDBMSプロダクトに続き5位をキープしています。
導入コスト
-
インストールのしやすさ
-
様々なプラットフォームに対応(Windows、Linux、MacOS等)
-
多くのプログラミング言語用ドライバの充実
-
Javascriptライクに書けるので、フロントエンジニアでも親しみやすい
-
レプリカの仕組みがRDBMSに比べて簡単
シャーディングもRDBMDに比べて簡単(RDBMSの場合、アクセス負荷を考慮した設計は大変)
设计思想(引自MongoDB的开发者10gen公司的CTO兼共同创始人Eliot Horowitz)
MongoDB 不是在实验室中设计而成的。我们根据构建大规模且具有高可用性的坚固系统的经验来创建 MongoDB。我们并非从零开始。我们采取的是找出存在的问题并解决它们的方法。
将MongoDB引入MongoDB发布为两个版本:Community和Enterprise。Community是MongoDB的开源版本,而Enterprise则提供了额外的管理、认证和监控功能。
本文所提到的环境如下所示。
操作系统为CentOS Linux 7.6.1810(核心版本)。
在CentOS上安装MongoDB。
-
/etc/yum.repos.d/mongodb-org-4.0.repoの作成
vi /etc/yum.repos.d/mongodb-org-4.0.repo
[mongodb-org-4.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc
-
yumレポジトリの有効確認
yum repolist mongodb-org-4.0 -v
プラグイン「fastestmirror」を読み込んでいます
Config time: 0.006
Yum version: 3.4.3
Loading mirror speeds from cached hostfile
* base: ftp-srv2.kddilabs.jp
* extras: ftp-srv2.kddilabs.jp
* updates: ftp-srv2.kddilabs.jp
Setting up Package Sacks
pkgsack time: 0.004
リポジトリー ID : mongodb-org-4.0/7
リポジトリーの名前 : MongoDB Repository
リポジトリーの状態 : 有効
リポジトリーのリビジョン : 1545246847
リポジトリー更新日 : Thu Dec 20 04:14:08 2018
リポジトリー内パッケージ数 : 30
リポジトリー容量 : 458 M
リポジトリー基準 URL : https://repo.mongodb.org/yum/redhat/7/mongodb-org/4.0/x86_64/
リポジトリーの期限 : 21,600 秒 (最終: Wed Jan 30 01:33:13 2019)
Filter : read-only:present
Repo ファイル名: /etc/yum.repos.d/mongodb-org-4.0.repo
repolist: 30
-
mongodb-orgパッケージのインストール
-
yum install -y mongodb-org
-
mongodb-orgパッケージのインストール 確認
yum list installed | grep mongodb-org
mongodb-org.x86_64 4.0.5-1.el7 @mongodb-org-4.0
mongodb-org-mongos.x86_64 4.0.5-1.el7 @mongodb-org-4.0
mongodb-org-server.x86_64 4.0.5-1.el7 @mongodb-org-4.0
mongodb-org-shell.x86_64 4.0.5-1.el7 @mongodb-org-4.0
mongodb-org-tools.x86_64 4.0.5-1.el7 @mongodb-org-4.0
-
mongodbサービス起動
-
systemctl start mongod
-
mongodbサービス起動確認
systemctl status mongod
● mongod.service - MongoDB Database Server
Loaded: loaded (/usr/lib/systemd/system/mongod.service; enabled; vendor preset: disabled)
Active: active (running) since 水 2019-01-30 02:06:26 JST; 1s ago
Docs: https://docs.mongodb.org/manual
Process: 4222 ExecStart=/usr/bin/mongod $OPTIONS (code=exited, status=0/SUCCESS)
Process: 4220 ExecStartPre=/usr/bin/chmod 0755 /var/run/mongodb (code=exited, status=0/SUCCESS)
Process: 4218 ExecStartPre=/usr/bin/chown mongod:mongod /var/run/mongodb (code=exited, status=0/SUCCESS)
Process: 4217 ExecStartPre=/usr/bin/mkdir -p /var/run/mongodb (code=exited, status=0/SUCCESS)
Main PID: 4225 (mongod)
CGroup: /system.slice/mongod.service
└─4225 /usr/bin/mongod -f /etc/mongod.conf
1月 30 02:06:25 localhost.localdomain systemd[1]: Starting MongoDB Database Server...
1月 30 02:06:25 localhost.localdomain mongod[4222]: about to fork child process, wait....
1月 30 02:06:25 localhost.localdomain mongod[4222]: forked process: 4225
1月 30 02:06:26 localhost.localdomain systemd[1]: Started MongoDB Database Server.
Hint: Some lines were ellipsized, use -l to show in full.
设定
如果要控制mongod数据库系统的运行,可以通过命令行或配置文件来进行控制。本文将简要介绍配置文件相关内容。
mongod的配置文件使用YAML格式进行描述。详细信息请参考“Configuration File Options”。另外,配置选项以配置文件为优先。
サンプル
systemLog:
destination: file
path: "/var/log/mongodb/mongod.log"
logAppend: true
storage:
journal:
enabled: true
processManagement:
fork: true
net:
bindIp: 127.0.0.1
port: 27017
setParameter:
enableLocalhostAuthBypass: false
...
在Mongo Shell中进行数据库操作。Mongo shell 是 MongoDB 的交互式 JavaScript 接口。可以使用 Mongo shell 查询和更新数据,执行管理操作。
创建数据库 – 创建集合
-
mongoシェル起動
-
mongo
-
データベースの作成
use testdb
switched to db testdb
-
データベースの確認
show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
在执行 <データベース名> 后,即使进行了一览显示,也无法看到所创建的数据库。至少需要注册一条或更多的数据。在创建集合后,将显示如下所示。
admin 0.000GB
config 0.000GB
local 0.000GB
testdb 0.000GB
举个例子,创建一个名为testcoll的集合,并插入文档。文档可以用JSON格式来描述。
-
ドキュメントの挿入(コレクションの作成)
-
db.testcoll.insert( { “key1” : “value1”, “key2” : “value2” } )
ハッシュと配列の混ざったドキュメントの挿入
db.testcoll.insert( { “array” : [ “Windows”, “Mac” , “Linux” ] } )
查阅文件
-
ドキュメントの参照(コレクション全てのデータを取得)
db.testcoll.find()
{ "_id" : ObjectId("5c6198f6fb5e83ffaa3ba044"), "key1" : "value1", "key2" : "value2" }
{ "_id" : ObjectId("5c61991ffb5e83ffaa3ba045"), "array" : [ "Windows", "Mac", "Linux" ] }
“_id” : ObjectId(“5c…”) 是MongoDB自动分配的。可以看作是RDBMS中的主键。
-
ドキュメントの参照(最初の1つのドキュメントを取得)
db.testcoll.findOne()
{
"_id" : ObjectId("5c6198f6fb5e83ffaa3ba044"),
"key1" : "value1",
"key2" : "value2"
}
-
ドキュメントの参照(ハッシュキーを引数に渡して値を取得)
db.testcoll.findOne()[“key1”]
value1
-
コレクションの確認
show collections
testcoll
用Javascript进行数据库操作
-
ドキュメントの挿入(forループでデータを挿入)
-
for (let i = 1; i <= 10; i++) db.testcoll2.insert( { x : 1 , y : i } )
-
検索結果に対するカーソル
-
var c = db.testcoll2.find()
while ( c.hasNext() ) printjson( c.next() )
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba046"), "x" : 1, "y" : 1 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba047"), "x" : 1, "y" : 2 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba048"), "x" : 1, "y" : 3 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba049"), "x" : 1, "y" : 4 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04a"), "x" : 1, "y" : 5 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04b"), "x" : 1, "y" : 6 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04c"), "x" : 1, "y" : 7 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04d"), "x" : 1, "y" : 8 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04e"), "x" : 1, "y" : 9 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04f"), "x" : 1, "y" : 10 }
-
ドキュメントを変数に格納
-
doc=db.testcoll2.findOne()
キー”key1″の値を表示
printjson(doc[“x”])
1
有关MongoDB的CRUD操作的详细信息,请参考MongoDB CRUD操作。
关闭数据库连接Mongo Shell时,可以使用以下命令来终止服务。
使用管理员
switched to db admin
关闭数据库服务器。
server should be down...
2019-02-12T00:53:59.058+0900 I NETWORK [js] trying reconnect to 127.0.0.1:27017 failed
2019-02-12T00:53:59.058+0900 I NETWORK [js] reconnect 127.0.0.1:27017 failed failed
退出();
MongoDB启动失败如果启动mongod失败,可能是由于使用了强制结束等方法导致锁定文件未被清除。
● mongod.service - MongoDB Database Server
Loaded: loaded (/usr/lib/systemd/system/mongod.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since 月 2019-02-11 23:47:18 JST; 47min ago
Docs: https://docs.mongodb.org/manual
Process: 3190 ExecStart=/usr/bin/mongod $OPTIONS (code=exited, status=14)
Process: 3185 ExecStartPre=/usr/bin/chmod 0755 /var/run/mongodb (code=exited, status=0/SUCCESS)
Process: 3181 ExecStartPre=/usr/bin/chown mongod:mongod /var/run/mongodb (code=exited, status=0/SUCCESS)
Process: 3176 ExecStartPre=/usr/bin/mkdir -p /var/run/mongodb (code=exited, status=0/SUCCESS)
2月 11 23:47:06 localhost.localdomain systemd[1]: Starting MongoDB Database Server...
2月 11 23:47:10 localhost.localdomain mongod[3190]: about to fork child process, wait....
2月 11 23:47:10 localhost.localdomain mongod[3190]: forked process: 3461
2月 11 23:47:18 localhost.localdomain systemd[1]: mongod.service: control process exi...4
2月 11 23:47:18 localhost.localdomain systemd[1]: Failed to start MongoDB Database Se....
2月 11 23:47:18 localhost.localdomain systemd[1]: Unit mongod.service entered failed ....
2月 11 23:47:18 localhost.localdomain systemd[1]: mongod.service failed.
Hint: Some lines were ellipsized, use -l to show in full.
如果是这种情况,执行以下命令并删除锁定文件,即可成功启动。
删除 /var/lib/mongo/mongod.lock
删除 /tmp/mongodb-27017.sock
如果/var/log/mongodb/mongod.log的日志中出现如下所示的“715: /var/lib/mongo/WiredTiger.turtle: handle-open: open: Permission denied”的记录,请检查/var/lib/mongo目录的权限。
2019-02-12T01:10:04.498+0900 E STORAGE [initandlisten] WiredTiger error (13) [1549901404:498011][3521:0x7f0ba3f22b80], wiredtiger_open: __posix_open_file, 715: /var/lib/mongo/WiredTiger.turtle: handle-open: open: Permission denied Raw: [1549901404:498011][3521:0x7f0ba3f22b80], wiredtiger_open: __posix_open_file, 715: /var/lib/mongo/WiredTiger.turtle: handle-open: open: Permission denied
使用 MongoDB 进行备份MongoDB的备份对象包括数据本身的备份和配置选项的备份。
对于配置选项,只需复制mongod启动shell或配置文件等文件即可。
另外,一般情况下,在数据备份过程中会使用完全备份和增量备份的组合方式,但是MongoDB并没有增量备份的功能。
MongoDB的备份方法
在MongoDB中,进行全备份有两种方法:
-
データファイルをコピーする方法
-
データベースを停止するか、ロックしておく必要がある
-
mongodumpを利用する方法
mongodumpデータベースの内容のバイナリエクスポートを作成するためのユーティリティ。mongodumpの場合、オンラインバックアップが可能
请注意以下事项:
由于索引在恢复过程中不会被转储,因此如果存在较大的索引,恢复的时间会较长。此外,虽然适用于备份和恢复小规模MongoDB部署的简单高效工具,但并不适用于获取大型系统的备份是理想的选择。
使用mongodump进行备份
-
バックアップ
mongodump
2019-02-12T01:28:20.371+0900 writing admin.system.version to
2019-02-12T01:28:20.372+0900 done dumping admin.system.version (1 document)
2019-02-12T01:28:20.372+0900 writing testdb.testcoll2 to
2019-02-12T01:28:20.372+0900 writing testdb.testcoll to
2019-02-12T01:28:20.379+0900 done dumping testdb.testcoll (2 documents)
2019-02-12T01:28:20.380+0900 done dumping testdb.testcoll2 (10 documents)
执行mongodump命令后,将在当前目录中创建一个名为dump的文件夹。该dump文件夹中存放着数据库的集合等数据的备份。
[root@localhost tmp]# ll dump/
合計 0
drwxr-xr-x. 2 root root 69 2月 12 01:28 admin
drwxr-xr-x. 2 root root 110 2月 12 01:28 testdb
使用mongodump进行恢复操作让我们试一试,在进行恢复之前删除之前创建的数据,然后确认数据是否恢复成功。
首先,我们分别删除testcoll和testcoll2这两个集合作为示例。
-
コレクションの削除
-
db.testcoll.drop();
db.testcoll2.drop();
我成功删除了集合,但数据库未能被删除,因此我也会删除数据库。
-
データベースの削除
db.dropDatabase();
{ "dropped" : "testdb", "ok" : 1 }
由于可以删除数据库,因此我们将进行恢复。
-
リストア
mongorestore ./dump
2019-02-12T03:32:42.592+0900 preparing collections to restore from
2019-02-12T03:32:42.594+0900 reading metadata for testdb.testcoll2 from dump/testdb/testcoll2.metadata.json
2019-02-12T03:32:42.608+0900 restoring testdb.testcoll2 from dump/testdb/testcoll2.bson
2019-02-12T03:32:42.611+0900 reading metadata for testdb.testcoll from dump/testdb/testcoll.metadata.json
2019-02-12T03:32:42.611+0900 no indexes to restore
2019-02-12T03:32:42.611+0900 finished restoring testdb.testcoll2 (10 documents)
2019-02-12T03:32:42.624+0900 restoring testdb.testcoll from dump/testdb/testcoll.bson
2019-02-12T03:32:42.627+0900 no indexes to restore
2019-02-12T03:32:42.627+0900 finished restoring testdb.testcoll (2 documents)
2019-02-12T03:32:42.627+0900 done
在执行还原操作后,连接到mongo shell以确认是否已经成功还原。
展示数据库
admin 0.000GB
config 0.000GB
local 0.000GB
testdb 0.000GB
展示集合
testcoll
testcoll2
在数据库中查找testcoll。
{ "_id" : ObjectId("5c6198f6fb5e83ffaa3ba044"), "key1" : "value1", "key2" : "value2" }
{ "_id" : ObjectId("5c61991ffb5e83ffaa3ba045"), "array" : [ "Windows", "Mac", "Linux" ] }
确认数据库、集合和文档已成功恢复。
监视
以下是有关监视mongod的命令:
-
コレクションの処理時間順に表示
mongotop
2019-02-12T01:34:41.789+0900 connected to: 127.0.0.1
ns total read write 2019-02-12T01:34:42+09:00
admin.system.roles 0ms 0ms 0ms
admin.system.version 0ms 0ms 0ms
config.system.sessions 0ms 0ms 0ms
local.startup_log 0ms 0ms 0ms
local.system.replset 0ms 0ms 0ms
testdb.testcoll 0ms 0ms 0ms
testdb.testcoll2 0ms 0ms 0ms
-
MongoDB全体の状態を表示
mongostat
time
*0 *0 *0 *0 0 2|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 158b 62.4k 1 Feb 12 01:35:25.188
*0 *0 *0 *0 0 1|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 157b 62.2k 1 Feb 12 01:35:26.188
*0 *0 *0 *0 0 1|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 157b 62.1k 1 Feb 12 01:35:27.190
*0 *0 *0 *0 0 2|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 158b 62.4k 1 Feb 12 01:35:28.187
*0 *0 *0 *0 0 1|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 157b 62.2k 1 Feb 12 01:35:29.187
*0 *0 *0 *0 0 1|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 157b 62.2k 1 Feb 12 01:35:30.188
*0 *0 *0 *0 0 2|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 158b 62.2k 1 Feb 12 01:35:31.187
-
MongoDB全体の統計情報(serverStatus()メソッド)
db.serverStatus()
{
"host" : "localhost.localdomain",
"version" : "4.0.5",
"process" : "mongod",
"pid" : NumberLong(3718),
"uptime" : 5961,
"uptimeMillis" : NumberLong(5961613),
"uptimeEstimate" : NumberLong(5961),
"localTime" : ISODate("2019-02-15T18:04:20.956Z"),
"asserts" : {
"regular" : 0,
"warning" : 0,
"msg" : 0,
"user" : 2,
"rollovers" : 0
},
"connections" : {
"current" : 1,
"available" : 51199,
"totalCreated" : 4
...
日志从版本3.0.0的新功能中,加上–logRotate reopen选项,可以按照典型的Linux/Unix日志轮换行为来打开日志文件。
首先,在/etc/mongod.conf文件中写入配置值”logRotate: reopen”,以描述MongoDB的日志轮转方法。
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
logRotate: reopen
接下来,我们将在/etc/logrotate.d/目录下为mongod创建一个日志轮换的配置文件。
打开 /etc/logrotate.d/mongod 文件进行编辑。
/var/log/mongodb/mongod.log {
daily
rotate 30
missingok
compress
delaycompress
notifempty
create 640 mongod mongod
sharedscripts
postrotate
/bin/kill -SIGUSR1 `cat /var/run/mongodb/mongod.pid 2>/dev/null` >/dev/null 2>&1
endscript
}
进行日志轮换测试,请执行以下命令:
logrotate -dv /etc/logrotate.d/mongod
reading config file /etc/logrotate.d/mongod
Allocating hash table for state file, size 15360 B
Handling 1 logs
rotating pattern: /var/log/mongodb/mongod.log after 1 days (30 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/mongodb/mongod.log
log does not need rotating (log has been already rotated)not running postrotate script, since no logs were rotated
当确认没有输出错误后,logrotate将自动执行日志轮换。
-rw-r-----. 1 mongod mongod 1385 2月 16 01:38 /var/log/mongodb/mongod.log
-rw-------. 1 mongod mongod 115166 2月 16 01:38 /var/log/mongodb/mongod.log.1
另外,在mongo shell连接时,您还可以使用以下命令手动进行日志轮转:
db.adminCommand( { logRotate:1 } )
{ "ok" : 1 }
创建用户
启用认证功能,并对数据库进行用户级别的访问控制。
首先,在连接Mongo shell时,执行以下命令以创建管理员用户。
使用管理者
db.createUser(
{
user: "admin",
pwd: "password",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
Successfully added user: {
"user" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
用户信息被保存在admin数据库中。而且,用户信息也存储在admin数据库的system.users集合中。
在用户管理中,有两种角色,分别是userAdmin与userAdminAnyDatabase。userAdmin是一种内置角色,仅可用于指定的数据库进行用户管理。而userAdminAnyDatabase是一种特殊的内置角色,只能用于admin数据库,并赋予了该角色的用户可以进行所有数据库的用户管理。
接下来,创建一个常规用户。使用 testdb。
db.createUser(
{
user: "testuser",
pwd: "password",
roles: [ { role: "readWrite", db: "testdb" } ]
}
)
Successfully added user: {
"user" : "testuser",
"roles" : [
{
"role" : "readWrite",
"db" : "testdb"
}
]
}
确认用户已创建。
使用管理员账户。
在系统用户中查找。
{ "_id" : "admin.admin", "user" : "admin", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "mBaj6lY+FmjRpDoXAq/9nA==", "storedKey" : "/zqpTgZEV2iUlFsXwybT7t2NeYI=", "serverKey" : "+m4wf2orLVRyntSJTLjbIsa23+Q=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "leY10lhgYGZHVm3FdcDqIKVig4ZSegW8lYBDzA==", "storedKey" : "gwSafO6sc4OqJTWJ2aJcYXQ4XnxdZFEYR4Bv4aGjyas=", "serverKey" : "n8D7GZboYIpkJf++35GXENDK8ubSWiksu23+OFNXcGE=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }
{ "_id" : "admin.testuser", "user" : "testuser", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "EVUclTLqMCIn1jtYqNBjWQ==", "storedKey" : "HQ1HiqS4FTMuVSH4wYuFPYMHBfI=", "serverKey" : "kQZPAh6kNqRlqoglY3k7D1864n8=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "KjnGdFe2WrAb5xhXdoAL25okfrc00uU1xI7Oow==", "storedKey" : "ZRUhnJPJrQBdgq94qcrRFOglQ3SgO/o5By5mKMKHMIk=", "serverKey" : "2N9s8GJLT7Q9dVT4Q33r/QehPK9H+ThgwK4EwQTvCWE=" } }, "roles" : [ { "role" : "readWrite", "db" : "testdb" } ] }
启用用户认证功能。
vi /etc/mongod.conf
security:
authorization: enabled
进行服务重启后,等待配置生效,连接到Mongo Shell并执行以下命令,确认身份验证功能已启用。
使用管理员身份查询数据库中的用户,命令为db.system.user.find()。
Error: error: {
"ok" : 0,
"errmsg" : "command find requires authentication",
"code" : 13,
"codeName" : "Unauthorized"
}
由于启用了身份验证功能,会输出错误信息,因此需要进行身份验证。
db.auth(“admin”,”password”)
1
再次执行命令,您可以确认用户信息。db.system.users.find()。
{ "_id" : "admin.admin", "user" : "admin", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "mBaj6lY+FmjRpDoXAq/9nA==", "storedKey" : "/zqpTgZEV2iUlFsXwybT7t2NeYI=", "serverKey" : "+m4wf2orLVRyntSJTLjbIsa23+Q=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "leY10lhgYGZHVm3FdcDqIKVig4ZSegW8lYBDzA==", "storedKey" : "gwSafO6sc4OqJTWJ2aJcYXQ4XnxdZFEYR4Bv4aGjyas=", "serverKey" : "n8D7GZboYIpkJf++35GXENDK8ubSWiksu23+OFNXcGE=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }
{ "_id" : "admin.testuser", "user" : "testuser", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "EVUclTLqMCIn1jtYqNBjWQ==", "storedKey" : "HQ1HiqS4FTMuVSH4wYuFPYMHBfI=", "serverKey" : "kQZPAh6kNqRlqoglY3k7D1864n8=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "KjnGdFe2WrAb5xhXdoAL25okfrc00uU1xI7Oow==", "storedKey" : "ZRUhnJPJrQBdgq94qcrRFOglQ3SgO/o5By5mKMKHMIk=", "serverKey" : "2N9s8GJLT7Q9dVT4Q33r/QehPK9H+ThgwK4EwQTvCWE=" } }, "roles" : [ { "role" : "readWrite", "db" : "testdb" } ] }
进行调查以下是MongoDB设计时的注意事项。
-
性能
シャーディングをしっかり組むこと
ドキュメント肥大化によりドキュメントの再配置が起こらないように、ドキュメントに必要なフィールドをあらかじめ作っておく
ジャーナルの書き込み回数を減らす
オンメモリを考慮し、全データをアクセスするような処理は行わない
運用
ハードウェア障害に備えて、バックアップファイルは別のサーバ上に退避させる
ディスク使用率やメモリ使用率のしきい値監視
クラウドの場合、DC被災時を考慮してレプリカセットを構築しておけば、DR切替が容易。
セキュリティ
デフォルトポートからの変更
クエリログの出力
データベースに対する外部からのアクセス制限及び認証
ディスク暗号化あるいは、データベースレイヤーでの暗号化(性能とトレードオフ)
请参考Welcome to the MongoDB Docs
The MongoDB 4.0 Manual
Install MongoDB Community Edition on Red Hat Enterprise or CentOS Linux
MongoDBの薄い本
MongoDBを始めた頃に知っていたら、と思う14のこと
Automating MongoDB Log Rotation
结束非关系型数据库(NoSQL)和MongoDB的吸引力在于其处理非传统数据结构的便利性以及现代化的设计,而这些都是SQL、PoostgreSQL和MySQL所不具备的。根据使用情况,性能、ACID等方面与关系型数据库管理系统(RDBMS)相比会出现一些优劣,因此我们将继续权衡取舍。

键值数据库 zhí shù jù kù)键值型数据库也被称为键值存储(KVS:Key-Value Store),它以键值对数组(关联数组)的形式来保存数据。其优点在于它的简单性,从而提供了良好的性能。
文档导向数据库 shù jù kù)ドキュメント指向データベースは、1件分のデータを「ドキュメント」としてデータを格納します。また、個々のドキュメントのデータ構造は自由で、データを追加する都度変えることができます。スキーマレスになるので、リレーショナルデータベースとは違って、事前にテーブルの構造を決めておく必要がありません。また、最大の利点は、スケーラビリティを重視していることです。大量のデータを扱うシステムにおいて、リレーショナルデータベースと比べて、比較的簡単にスケールできるような仕組みを持っていることが一般的です。MongoDBは、ドキュメント指向データベースになります。
指向数据库的列将适合列方向操作的数据库称为”列式数据库”。频繁进行列方向操作时,性能会得到优势。
MongoDB概要作为支撑互联网技术的一部分,Ajax和WebAPI已被广泛采用,几乎所有的网站都在使用,并且还有JavaScript、JSON和YAML等相关技术作为补充支持。
指向数据库的列将适合列方向操作的数据库称为”列式数据库”。频繁进行列方向操作时,性能会得到优势。
MongoDB概要作为支撑互联网技术的一部分,Ajax和WebAPI已被广泛采用,几乎所有的网站都在使用,并且还有JavaScript、JSON和YAML等相关技术作为补充支持。
昨今、WebAPIでデータ取得する場合は、JSONがデファクトスタンダードだと思います。
しかし、従来のRDBMSでは、階層的なJSONのスキーマ定義をすることは困難であり、WebAPIは仕様変更されることも多く、その度にスキーマを変更するのは大変です。
基於這樣的背景,MongoDB誕生了。

建筑设计
-
RDBMSのようにレコードをテーブルに格納するのではなく、「ドキュメント」と呼ばれる構造的データをJSONライクな形式で表現し、そのドキュメントの集合を「コレクション」として管理する
-
コレクションはスキーマレスなドキュメントで格納され、任意のフィールドを好きなときに追加できる
-
ドキュメントには複雑な階層構造を持たせることもでき、それらの構造に含まれるフィールドを指定したクエリやインデックス生成も簡単な指定によって行える
-
KVSでは苦手なValueを検索の条件としたり、ソート・集計を実現できる
永続性を提供
MongoDBは、以下のようなシステムに適しています。
-
Webサイトの操作データログの蓄積
-
アドホックなフィールドを検索対象とするコンテンツ
ソーシャルゲーム
でも、MongoDBは以下のことができません。
-
NoSQLなので、SQLは使用できない。クエリはJavaScriptで行う
-
RDBMSのように高度な結合操作(joinに相当する2つの関係から1つの関係を返す演算処理)
トランザクション処理(※)
(※)MongoDB 4.0 でマルチドキュメントトランザクションがサポートされました。これにより、RDBMS likeのような一貫性のある処理を行うことができますが、以下の条件が必要です。
-
レプリカセット構成あるいはシャーディング構成
-
Feature Compatibility Version(FCV)4.0以降
WiredTigerストレージエンジン(※)
(※)MongoDB2.6まではストレージエンジンがMMAPv1、MongoDB3.2からWiredTigerがデフォルト
因此,如果需要涉及多个事务的查询,则MongoDB并不适合。
端的にいうと、MongoDBは万全ではありません。
適材適所になるのでシステムに合わせてRDBMSと使い分けが必要です。
基本は、MongoDBは非正規化したドキュメント構造を扱っているので、どうしても分割されてしまうドキュメントに対しての排他処理を行いたい場合に、マルチドキュメントトランザクションを使用すればいいのではないかと考えます。
機能
-
レプリカ
-
レプリケーションを構成することで障害耐性も高め、フェールオーバーが簡単にできる。RDBMSで言うLifeKeeperのような商用ソフトウェアは不要。
-
シャーディングで水平スケーリングが可能
-
スケールアウトが容易に可能になり、RDBMSよりも高速なレスポンスが得られることがある
-
(逆説的に言うと非正規形前提で設計しているので、結合演算が不要な場合はそのパフォーマンスを発揮する)
-
GridFSと呼ばれるプロトコルを使用することで、大きなファイルをデータベースに格納・取得することができる
インメモリ機能により、高速なReadを実現するためにpageと言う単位でデータをメモリに保持している
(※)厳密に言うと、ファイルシステムに格納されているコレクションをmmapしている
(※)メモリ内に無いデータはディスクからロードすることになる、(Page Fault)
そのため、Page FaultはメモリからReadする場合と比較して時間がかかってしまう
其他
共享
DB-Enginesによると、2019年2月の時点でOracle Database、MySQL、Microsoft SQL Server、PostgreSQL等の歴史あるRDBMSプロダクトに続き5位をキープしています。
導入コスト
-
インストールのしやすさ
-
様々なプラットフォームに対応(Windows、Linux、MacOS等)
-
多くのプログラミング言語用ドライバの充実
-
Javascriptライクに書けるので、フロントエンジニアでも親しみやすい
-
レプリカの仕組みがRDBMSに比べて簡単
シャーディングもRDBMDに比べて簡単(RDBMSの場合、アクセス負荷を考慮した設計は大変)
设计思想(引自MongoDB的开发者10gen公司的CTO兼共同创始人Eliot Horowitz)
MongoDB 不是在实验室中设计而成的。我们根据构建大规模且具有高可用性的坚固系统的经验来创建 MongoDB。我们并非从零开始。我们采取的是找出存在的问题并解决它们的方法。
将MongoDB引入MongoDB发布为两个版本:Community和Enterprise。Community是MongoDB的开源版本,而Enterprise则提供了额外的管理、认证和监控功能。
本文所提到的环境如下所示。
操作系统为CentOS Linux 7.6.1810(核心版本)。
在CentOS上安装MongoDB。
-
/etc/yum.repos.d/mongodb-org-4.0.repoの作成
vi /etc/yum.repos.d/mongodb-org-4.0.repo
[mongodb-org-4.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc
-
yumレポジトリの有効確認
yum repolist mongodb-org-4.0 -v
プラグイン「fastestmirror」を読み込んでいます
Config time: 0.006
Yum version: 3.4.3
Loading mirror speeds from cached hostfile
* base: ftp-srv2.kddilabs.jp
* extras: ftp-srv2.kddilabs.jp
* updates: ftp-srv2.kddilabs.jp
Setting up Package Sacks
pkgsack time: 0.004
リポジトリー ID : mongodb-org-4.0/7
リポジトリーの名前 : MongoDB Repository
リポジトリーの状態 : 有効
リポジトリーのリビジョン : 1545246847
リポジトリー更新日 : Thu Dec 20 04:14:08 2018
リポジトリー内パッケージ数 : 30
リポジトリー容量 : 458 M
リポジトリー基準 URL : https://repo.mongodb.org/yum/redhat/7/mongodb-org/4.0/x86_64/
リポジトリーの期限 : 21,600 秒 (最終: Wed Jan 30 01:33:13 2019)
Filter : read-only:present
Repo ファイル名: /etc/yum.repos.d/mongodb-org-4.0.repo
repolist: 30
-
mongodb-orgパッケージのインストール
-
yum install -y mongodb-org
-
mongodb-orgパッケージのインストール 確認
yum list installed | grep mongodb-org
mongodb-org.x86_64 4.0.5-1.el7 @mongodb-org-4.0
mongodb-org-mongos.x86_64 4.0.5-1.el7 @mongodb-org-4.0
mongodb-org-server.x86_64 4.0.5-1.el7 @mongodb-org-4.0
mongodb-org-shell.x86_64 4.0.5-1.el7 @mongodb-org-4.0
mongodb-org-tools.x86_64 4.0.5-1.el7 @mongodb-org-4.0
-
mongodbサービス起動
-
systemctl start mongod
-
mongodbサービス起動確認
systemctl status mongod
● mongod.service - MongoDB Database Server
Loaded: loaded (/usr/lib/systemd/system/mongod.service; enabled; vendor preset: disabled)
Active: active (running) since 水 2019-01-30 02:06:26 JST; 1s ago
Docs: https://docs.mongodb.org/manual
Process: 4222 ExecStart=/usr/bin/mongod $OPTIONS (code=exited, status=0/SUCCESS)
Process: 4220 ExecStartPre=/usr/bin/chmod 0755 /var/run/mongodb (code=exited, status=0/SUCCESS)
Process: 4218 ExecStartPre=/usr/bin/chown mongod:mongod /var/run/mongodb (code=exited, status=0/SUCCESS)
Process: 4217 ExecStartPre=/usr/bin/mkdir -p /var/run/mongodb (code=exited, status=0/SUCCESS)
Main PID: 4225 (mongod)
CGroup: /system.slice/mongod.service
└─4225 /usr/bin/mongod -f /etc/mongod.conf
1月 30 02:06:25 localhost.localdomain systemd[1]: Starting MongoDB Database Server...
1月 30 02:06:25 localhost.localdomain mongod[4222]: about to fork child process, wait....
1月 30 02:06:25 localhost.localdomain mongod[4222]: forked process: 4225
1月 30 02:06:26 localhost.localdomain systemd[1]: Started MongoDB Database Server.
Hint: Some lines were ellipsized, use -l to show in full.
设定
如果要控制mongod数据库系统的运行,可以通过命令行或配置文件来进行控制。本文将简要介绍配置文件相关内容。
mongod的配置文件使用YAML格式进行描述。详细信息请参考“Configuration File Options”。另外,配置选项以配置文件为优先。
サンプル
systemLog:
destination: file
path: "/var/log/mongodb/mongod.log"
logAppend: true
storage:
journal:
enabled: true
processManagement:
fork: true
net:
bindIp: 127.0.0.1
port: 27017
setParameter:
enableLocalhostAuthBypass: false
...
在Mongo Shell中进行数据库操作。Mongo shell 是 MongoDB 的交互式 JavaScript 接口。可以使用 Mongo shell 查询和更新数据,执行管理操作。
创建数据库 – 创建集合
-
mongoシェル起動
-
mongo
-
データベースの作成
use testdb
switched to db testdb
-
データベースの確認
show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
在执行 <データベース名> 后,即使进行了一览显示,也无法看到所创建的数据库。至少需要注册一条或更多的数据。在创建集合后,将显示如下所示。
admin 0.000GB
config 0.000GB
local 0.000GB
testdb 0.000GB
举个例子,创建一个名为testcoll的集合,并插入文档。文档可以用JSON格式来描述。
-
ドキュメントの挿入(コレクションの作成)
-
db.testcoll.insert( { “key1” : “value1”, “key2” : “value2” } )
ハッシュと配列の混ざったドキュメントの挿入
db.testcoll.insert( { “array” : [ “Windows”, “Mac” , “Linux” ] } )
查阅文件
-
ドキュメントの参照(コレクション全てのデータを取得)
db.testcoll.find()
{ "_id" : ObjectId("5c6198f6fb5e83ffaa3ba044"), "key1" : "value1", "key2" : "value2" }
{ "_id" : ObjectId("5c61991ffb5e83ffaa3ba045"), "array" : [ "Windows", "Mac", "Linux" ] }
“_id” : ObjectId(“5c…”) 是MongoDB自动分配的。可以看作是RDBMS中的主键。
-
ドキュメントの参照(最初の1つのドキュメントを取得)
db.testcoll.findOne()
{
"_id" : ObjectId("5c6198f6fb5e83ffaa3ba044"),
"key1" : "value1",
"key2" : "value2"
}
-
ドキュメントの参照(ハッシュキーを引数に渡して値を取得)
db.testcoll.findOne()[“key1”]
value1
-
コレクションの確認
show collections
testcoll
用Javascript进行数据库操作
-
ドキュメントの挿入(forループでデータを挿入)
-
for (let i = 1; i <= 10; i++) db.testcoll2.insert( { x : 1 , y : i } )
-
検索結果に対するカーソル
-
var c = db.testcoll2.find()
while ( c.hasNext() ) printjson( c.next() )
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba046"), "x" : 1, "y" : 1 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba047"), "x" : 1, "y" : 2 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba048"), "x" : 1, "y" : 3 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba049"), "x" : 1, "y" : 4 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04a"), "x" : 1, "y" : 5 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04b"), "x" : 1, "y" : 6 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04c"), "x" : 1, "y" : 7 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04d"), "x" : 1, "y" : 8 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04e"), "x" : 1, "y" : 9 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04f"), "x" : 1, "y" : 10 }
-
ドキュメントを変数に格納
-
doc=db.testcoll2.findOne()
キー”key1″の値を表示
printjson(doc[“x”])
1
有关MongoDB的CRUD操作的详细信息,请参考MongoDB CRUD操作。
关闭数据库连接Mongo Shell时,可以使用以下命令来终止服务。
使用管理员
switched to db admin
关闭数据库服务器。
server should be down...
2019-02-12T00:53:59.058+0900 I NETWORK [js] trying reconnect to 127.0.0.1:27017 failed
2019-02-12T00:53:59.058+0900 I NETWORK [js] reconnect 127.0.0.1:27017 failed failed
退出();
MongoDB启动失败如果启动mongod失败,可能是由于使用了强制结束等方法导致锁定文件未被清除。
● mongod.service - MongoDB Database Server
Loaded: loaded (/usr/lib/systemd/system/mongod.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since 月 2019-02-11 23:47:18 JST; 47min ago
Docs: https://docs.mongodb.org/manual
Process: 3190 ExecStart=/usr/bin/mongod $OPTIONS (code=exited, status=14)
Process: 3185 ExecStartPre=/usr/bin/chmod 0755 /var/run/mongodb (code=exited, status=0/SUCCESS)
Process: 3181 ExecStartPre=/usr/bin/chown mongod:mongod /var/run/mongodb (code=exited, status=0/SUCCESS)
Process: 3176 ExecStartPre=/usr/bin/mkdir -p /var/run/mongodb (code=exited, status=0/SUCCESS)
2月 11 23:47:06 localhost.localdomain systemd[1]: Starting MongoDB Database Server...
2月 11 23:47:10 localhost.localdomain mongod[3190]: about to fork child process, wait....
2月 11 23:47:10 localhost.localdomain mongod[3190]: forked process: 3461
2月 11 23:47:18 localhost.localdomain systemd[1]: mongod.service: control process exi...4
2月 11 23:47:18 localhost.localdomain systemd[1]: Failed to start MongoDB Database Se....
2月 11 23:47:18 localhost.localdomain systemd[1]: Unit mongod.service entered failed ....
2月 11 23:47:18 localhost.localdomain systemd[1]: mongod.service failed.
Hint: Some lines were ellipsized, use -l to show in full.
如果是这种情况,执行以下命令并删除锁定文件,即可成功启动。
删除 /var/lib/mongo/mongod.lock
删除 /tmp/mongodb-27017.sock
如果/var/log/mongodb/mongod.log的日志中出现如下所示的“715: /var/lib/mongo/WiredTiger.turtle: handle-open: open: Permission denied”的记录,请检查/var/lib/mongo目录的权限。
2019-02-12T01:10:04.498+0900 E STORAGE [initandlisten] WiredTiger error (13) [1549901404:498011][3521:0x7f0ba3f22b80], wiredtiger_open: __posix_open_file, 715: /var/lib/mongo/WiredTiger.turtle: handle-open: open: Permission denied Raw: [1549901404:498011][3521:0x7f0ba3f22b80], wiredtiger_open: __posix_open_file, 715: /var/lib/mongo/WiredTiger.turtle: handle-open: open: Permission denied
使用 MongoDB 进行备份MongoDB的备份对象包括数据本身的备份和配置选项的备份。
对于配置选项,只需复制mongod启动shell或配置文件等文件即可。
另外,一般情况下,在数据备份过程中会使用完全备份和增量备份的组合方式,但是MongoDB并没有增量备份的功能。
MongoDB的备份方法
在MongoDB中,进行全备份有两种方法:
-
データファイルをコピーする方法
-
データベースを停止するか、ロックしておく必要がある
-
mongodumpを利用する方法
mongodumpデータベースの内容のバイナリエクスポートを作成するためのユーティリティ。mongodumpの場合、オンラインバックアップが可能
请注意以下事项:
由于索引在恢复过程中不会被转储,因此如果存在较大的索引,恢复的时间会较长。此外,虽然适用于备份和恢复小规模MongoDB部署的简单高效工具,但并不适用于获取大型系统的备份是理想的选择。
使用mongodump进行备份
-
バックアップ
mongodump
2019-02-12T01:28:20.371+0900 writing admin.system.version to
2019-02-12T01:28:20.372+0900 done dumping admin.system.version (1 document)
2019-02-12T01:28:20.372+0900 writing testdb.testcoll2 to
2019-02-12T01:28:20.372+0900 writing testdb.testcoll to
2019-02-12T01:28:20.379+0900 done dumping testdb.testcoll (2 documents)
2019-02-12T01:28:20.380+0900 done dumping testdb.testcoll2 (10 documents)
执行mongodump命令后,将在当前目录中创建一个名为dump的文件夹。该dump文件夹中存放着数据库的集合等数据的备份。
[root@localhost tmp]# ll dump/
合計 0
drwxr-xr-x. 2 root root 69 2月 12 01:28 admin
drwxr-xr-x. 2 root root 110 2月 12 01:28 testdb
使用mongodump进行恢复操作让我们试一试,在进行恢复之前删除之前创建的数据,然后确认数据是否恢复成功。
首先,我们分别删除testcoll和testcoll2这两个集合作为示例。
-
コレクションの削除
-
db.testcoll.drop();
db.testcoll2.drop();
我成功删除了集合,但数据库未能被删除,因此我也会删除数据库。
-
データベースの削除
db.dropDatabase();
{ "dropped" : "testdb", "ok" : 1 }
由于可以删除数据库,因此我们将进行恢复。
-
リストア
mongorestore ./dump
2019-02-12T03:32:42.592+0900 preparing collections to restore from
2019-02-12T03:32:42.594+0900 reading metadata for testdb.testcoll2 from dump/testdb/testcoll2.metadata.json
2019-02-12T03:32:42.608+0900 restoring testdb.testcoll2 from dump/testdb/testcoll2.bson
2019-02-12T03:32:42.611+0900 reading metadata for testdb.testcoll from dump/testdb/testcoll.metadata.json
2019-02-12T03:32:42.611+0900 no indexes to restore
2019-02-12T03:32:42.611+0900 finished restoring testdb.testcoll2 (10 documents)
2019-02-12T03:32:42.624+0900 restoring testdb.testcoll from dump/testdb/testcoll.bson
2019-02-12T03:32:42.627+0900 no indexes to restore
2019-02-12T03:32:42.627+0900 finished restoring testdb.testcoll (2 documents)
2019-02-12T03:32:42.627+0900 done
在执行还原操作后,连接到mongo shell以确认是否已经成功还原。
展示数据库
admin 0.000GB
config 0.000GB
local 0.000GB
testdb 0.000GB
展示集合
testcoll
testcoll2
在数据库中查找testcoll。
{ "_id" : ObjectId("5c6198f6fb5e83ffaa3ba044"), "key1" : "value1", "key2" : "value2" }
{ "_id" : ObjectId("5c61991ffb5e83ffaa3ba045"), "array" : [ "Windows", "Mac", "Linux" ] }
确认数据库、集合和文档已成功恢复。
监视
以下是有关监视mongod的命令:
-
コレクションの処理時間順に表示
mongotop
2019-02-12T01:34:41.789+0900 connected to: 127.0.0.1
ns total read write 2019-02-12T01:34:42+09:00
admin.system.roles 0ms 0ms 0ms
admin.system.version 0ms 0ms 0ms
config.system.sessions 0ms 0ms 0ms
local.startup_log 0ms 0ms 0ms
local.system.replset 0ms 0ms 0ms
testdb.testcoll 0ms 0ms 0ms
testdb.testcoll2 0ms 0ms 0ms
-
MongoDB全体の状態を表示
mongostat
time
*0 *0 *0 *0 0 2|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 158b 62.4k 1 Feb 12 01:35:25.188
*0 *0 *0 *0 0 1|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 157b 62.2k 1 Feb 12 01:35:26.188
*0 *0 *0 *0 0 1|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 157b 62.1k 1 Feb 12 01:35:27.190
*0 *0 *0 *0 0 2|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 158b 62.4k 1 Feb 12 01:35:28.187
*0 *0 *0 *0 0 1|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 157b 62.2k 1 Feb 12 01:35:29.187
*0 *0 *0 *0 0 1|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 157b 62.2k 1 Feb 12 01:35:30.188
*0 *0 *0 *0 0 2|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 158b 62.2k 1 Feb 12 01:35:31.187
-
MongoDB全体の統計情報(serverStatus()メソッド)
db.serverStatus()
{
"host" : "localhost.localdomain",
"version" : "4.0.5",
"process" : "mongod",
"pid" : NumberLong(3718),
"uptime" : 5961,
"uptimeMillis" : NumberLong(5961613),
"uptimeEstimate" : NumberLong(5961),
"localTime" : ISODate("2019-02-15T18:04:20.956Z"),
"asserts" : {
"regular" : 0,
"warning" : 0,
"msg" : 0,
"user" : 2,
"rollovers" : 0
},
"connections" : {
"current" : 1,
"available" : 51199,
"totalCreated" : 4
...
日志从版本3.0.0的新功能中,加上–logRotate reopen选项,可以按照典型的Linux/Unix日志轮换行为来打开日志文件。
首先,在/etc/mongod.conf文件中写入配置值”logRotate: reopen”,以描述MongoDB的日志轮转方法。
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
logRotate: reopen
接下来,我们将在/etc/logrotate.d/目录下为mongod创建一个日志轮换的配置文件。
打开 /etc/logrotate.d/mongod 文件进行编辑。
/var/log/mongodb/mongod.log {
daily
rotate 30
missingok
compress
delaycompress
notifempty
create 640 mongod mongod
sharedscripts
postrotate
/bin/kill -SIGUSR1 `cat /var/run/mongodb/mongod.pid 2>/dev/null` >/dev/null 2>&1
endscript
}
进行日志轮换测试,请执行以下命令:
logrotate -dv /etc/logrotate.d/mongod
reading config file /etc/logrotate.d/mongod
Allocating hash table for state file, size 15360 B
Handling 1 logs
rotating pattern: /var/log/mongodb/mongod.log after 1 days (30 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/mongodb/mongod.log
log does not need rotating (log has been already rotated)not running postrotate script, since no logs were rotated
当确认没有输出错误后,logrotate将自动执行日志轮换。
-rw-r-----. 1 mongod mongod 1385 2月 16 01:38 /var/log/mongodb/mongod.log
-rw-------. 1 mongod mongod 115166 2月 16 01:38 /var/log/mongodb/mongod.log.1
另外,在mongo shell连接时,您还可以使用以下命令手动进行日志轮转:
db.adminCommand( { logRotate:1 } )
{ "ok" : 1 }
创建用户
启用认证功能,并对数据库进行用户级别的访问控制。
首先,在连接Mongo shell时,执行以下命令以创建管理员用户。
使用管理者
db.createUser(
{
user: "admin",
pwd: "password",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
Successfully added user: {
"user" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
用户信息被保存在admin数据库中。而且,用户信息也存储在admin数据库的system.users集合中。
在用户管理中,有两种角色,分别是userAdmin与userAdminAnyDatabase。userAdmin是一种内置角色,仅可用于指定的数据库进行用户管理。而userAdminAnyDatabase是一种特殊的内置角色,只能用于admin数据库,并赋予了该角色的用户可以进行所有数据库的用户管理。
接下来,创建一个常规用户。使用 testdb。
db.createUser(
{
user: "testuser",
pwd: "password",
roles: [ { role: "readWrite", db: "testdb" } ]
}
)
Successfully added user: {
"user" : "testuser",
"roles" : [
{
"role" : "readWrite",
"db" : "testdb"
}
]
}
确认用户已创建。
使用管理员账户。
在系统用户中查找。
{ "_id" : "admin.admin", "user" : "admin", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "mBaj6lY+FmjRpDoXAq/9nA==", "storedKey" : "/zqpTgZEV2iUlFsXwybT7t2NeYI=", "serverKey" : "+m4wf2orLVRyntSJTLjbIsa23+Q=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "leY10lhgYGZHVm3FdcDqIKVig4ZSegW8lYBDzA==", "storedKey" : "gwSafO6sc4OqJTWJ2aJcYXQ4XnxdZFEYR4Bv4aGjyas=", "serverKey" : "n8D7GZboYIpkJf++35GXENDK8ubSWiksu23+OFNXcGE=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }
{ "_id" : "admin.testuser", "user" : "testuser", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "EVUclTLqMCIn1jtYqNBjWQ==", "storedKey" : "HQ1HiqS4FTMuVSH4wYuFPYMHBfI=", "serverKey" : "kQZPAh6kNqRlqoglY3k7D1864n8=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "KjnGdFe2WrAb5xhXdoAL25okfrc00uU1xI7Oow==", "storedKey" : "ZRUhnJPJrQBdgq94qcrRFOglQ3SgO/o5By5mKMKHMIk=", "serverKey" : "2N9s8GJLT7Q9dVT4Q33r/QehPK9H+ThgwK4EwQTvCWE=" } }, "roles" : [ { "role" : "readWrite", "db" : "testdb" } ] }
启用用户认证功能。
vi /etc/mongod.conf
security:
authorization: enabled
进行服务重启后,等待配置生效,连接到Mongo Shell并执行以下命令,确认身份验证功能已启用。
使用管理员身份查询数据库中的用户,命令为db.system.user.find()。
Error: error: {
"ok" : 0,
"errmsg" : "command find requires authentication",
"code" : 13,
"codeName" : "Unauthorized"
}
由于启用了身份验证功能,会输出错误信息,因此需要进行身份验证。
db.auth(“admin”,”password”)
1
再次执行命令,您可以确认用户信息。db.system.users.find()。
{ "_id" : "admin.admin", "user" : "admin", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "mBaj6lY+FmjRpDoXAq/9nA==", "storedKey" : "/zqpTgZEV2iUlFsXwybT7t2NeYI=", "serverKey" : "+m4wf2orLVRyntSJTLjbIsa23+Q=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "leY10lhgYGZHVm3FdcDqIKVig4ZSegW8lYBDzA==", "storedKey" : "gwSafO6sc4OqJTWJ2aJcYXQ4XnxdZFEYR4Bv4aGjyas=", "serverKey" : "n8D7GZboYIpkJf++35GXENDK8ubSWiksu23+OFNXcGE=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }
{ "_id" : "admin.testuser", "user" : "testuser", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "EVUclTLqMCIn1jtYqNBjWQ==", "storedKey" : "HQ1HiqS4FTMuVSH4wYuFPYMHBfI=", "serverKey" : "kQZPAh6kNqRlqoglY3k7D1864n8=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "KjnGdFe2WrAb5xhXdoAL25okfrc00uU1xI7Oow==", "storedKey" : "ZRUhnJPJrQBdgq94qcrRFOglQ3SgO/o5By5mKMKHMIk=", "serverKey" : "2N9s8GJLT7Q9dVT4Q33r/QehPK9H+ThgwK4EwQTvCWE=" } }, "roles" : [ { "role" : "readWrite", "db" : "testdb" } ] }
进行调查以下是MongoDB设计时的注意事项。
-
性能
シャーディングをしっかり組むこと
ドキュメント肥大化によりドキュメントの再配置が起こらないように、ドキュメントに必要なフィールドをあらかじめ作っておく
ジャーナルの書き込み回数を減らす
オンメモリを考慮し、全データをアクセスするような処理は行わない
運用
ハードウェア障害に備えて、バックアップファイルは別のサーバ上に退避させる
ディスク使用率やメモリ使用率のしきい値監視
クラウドの場合、DC被災時を考慮してレプリカセットを構築しておけば、DR切替が容易。
セキュリティ
デフォルトポートからの変更
クエリログの出力
データベースに対する外部からのアクセス制限及び認証
ディスク暗号化あるいは、データベースレイヤーでの暗号化(性能とトレードオフ)
请参考Welcome to the MongoDB Docs
The MongoDB 4.0 Manual
Install MongoDB Community Edition on Red Hat Enterprise or CentOS Linux
MongoDBの薄い本
MongoDBを始めた頃に知っていたら、と思う14のこと
Automating MongoDB Log Rotation
结束非关系型数据库(NoSQL)和MongoDB的吸引力在于其处理非传统数据结构的便利性以及现代化的设计,而这些都是SQL、PoostgreSQL和MySQL所不具备的。根据使用情况,性能、ACID等方面与关系型数据库管理系统(RDBMS)相比会出现一些优劣,因此我们将继续权衡取舍。

-
- RDBMSのようにレコードをテーブルに格納するのではなく、「ドキュメント」と呼ばれる構造的データをJSONライクな形式で表現し、そのドキュメントの集合を「コレクション」として管理する
-
- コレクションはスキーマレスなドキュメントで格納され、任意のフィールドを好きなときに追加できる
-
- ドキュメントには複雑な階層構造を持たせることもでき、それらの構造に含まれるフィールドを指定したクエリやインデックス生成も簡単な指定によって行える
-
- KVSでは苦手なValueを検索の条件としたり、ソート・集計を実現できる
永続性を提供
MongoDBは、以下のようなシステムに適しています。
-
- Webサイトの操作データログの蓄積
-
- アドホックなフィールドを検索対象とするコンテンツ
- ソーシャルゲーム
でも、MongoDBは以下のことができません。
-
- NoSQLなので、SQLは使用できない。クエリはJavaScriptで行う
-
- RDBMSのように高度な結合操作(joinに相当する2つの関係から1つの関係を返す演算処理)
- トランザクション処理(※)
(※)MongoDB 4.0 でマルチドキュメントトランザクションがサポートされました。これにより、RDBMS likeのような一貫性のある処理を行うことができますが、以下の条件が必要です。
-
- レプリカセット構成あるいはシャーディング構成
-
- Feature Compatibility Version(FCV)4.0以降
WiredTigerストレージエンジン(※)
(※)MongoDB2.6まではストレージエンジンがMMAPv1、MongoDB3.2からWiredTigerがデフォルト
因此,如果需要涉及多个事务的查询,则MongoDB并不适合。
端的にいうと、MongoDBは万全ではありません。
適材適所になるのでシステムに合わせてRDBMSと使い分けが必要です。
基本は、MongoDBは非正規化したドキュメント構造を扱っているので、どうしても分割されてしまうドキュメントに対しての排他処理を行いたい場合に、マルチドキュメントトランザクションを使用すればいいのではないかと考えます。
機能
-
レプリカ
- レプリカ
-
- レプリケーションを構成することで障害耐性も高め、フェールオーバーが簡単にできる。RDBMSで言うLifeKeeperのような商用ソフトウェアは不要。
-
- シャーディングで水平スケーリングが可能
-
- スケールアウトが容易に可能になり、RDBMSよりも高速なレスポンスが得られることがある
-
- (逆説的に言うと非正規形前提で設計しているので、結合演算が不要な場合はそのパフォーマンスを発揮する)
-
- GridFSと呼ばれるプロトコルを使用することで、大きなファイルをデータベースに格納・取得することができる
- インメモリ機能により、高速なReadを実現するためにpageと言う単位でデータをメモリに保持している
(※)厳密に言うと、ファイルシステムに格納されているコレクションをmmapしている
(※)メモリ内に無いデータはディスクからロードすることになる、(Page Fault)
そのため、Page FaultはメモリからReadする場合と比較して時間がかかってしまう
其他
共享
DB-Enginesによると、2019年2月の時点でOracle Database、MySQL、Microsoft SQL Server、PostgreSQL等の歴史あるRDBMSプロダクトに続き5位をキープしています。
導入コスト
-
インストールのしやすさ
DB-Enginesによると、2019年2月の時点でOracle Database、MySQL、Microsoft SQL Server、PostgreSQL等の歴史あるRDBMSプロダクトに続き5位をキープしています。
導入コスト
-
インストールのしやすさ
- インストールのしやすさ
-
- 様々なプラットフォームに対応(Windows、Linux、MacOS等)
-
- 多くのプログラミング言語用ドライバの充実
-
- Javascriptライクに書けるので、フロントエンジニアでも親しみやすい
-
- レプリカの仕組みがRDBMSに比べて簡単
- シャーディングもRDBMDに比べて簡単(RDBMSの場合、アクセス負荷を考慮した設計は大変)
设计思想(引自MongoDB的开发者10gen公司的CTO兼共同创始人Eliot Horowitz)
MongoDB 不是在实验室中设计而成的。我们根据构建大规模且具有高可用性的坚固系统的经验来创建 MongoDB。我们并非从零开始。我们采取的是找出存在的问题并解决它们的方法。
将MongoDB引入MongoDB发布为两个版本:Community和Enterprise。Community是MongoDB的开源版本,而Enterprise则提供了额外的管理、认证和监控功能。
MongoDB 不是在实验室中设计而成的。我们根据构建大规模且具有高可用性的坚固系统的经验来创建 MongoDB。我们并非从零开始。我们采取的是找出存在的问题并解决它们的方法。
本文所提到的环境如下所示。
操作系统为CentOS Linux 7.6.1810(核心版本)。
在CentOS上安装MongoDB。
-
/etc/yum.repos.d/mongodb-org-4.0.repoの作成
- /etc/yum.repos.d/mongodb-org-4.0.repoの作成
- vi /etc/yum.repos.d/mongodb-org-4.0.repo
[mongodb-org-4.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc
-
- yumレポジトリの有効確認
- yum repolist mongodb-org-4.0 -v
プラグイン「fastestmirror」を読み込んでいます
Config time: 0.006
Yum version: 3.4.3
Loading mirror speeds from cached hostfile
* base: ftp-srv2.kddilabs.jp
* extras: ftp-srv2.kddilabs.jp
* updates: ftp-srv2.kddilabs.jp
Setting up Package Sacks
pkgsack time: 0.004
リポジトリー ID : mongodb-org-4.0/7
リポジトリーの名前 : MongoDB Repository
リポジトリーの状態 : 有効
リポジトリーのリビジョン : 1545246847
リポジトリー更新日 : Thu Dec 20 04:14:08 2018
リポジトリー内パッケージ数 : 30
リポジトリー容量 : 458 M
リポジトリー基準 URL : https://repo.mongodb.org/yum/redhat/7/mongodb-org/4.0/x86_64/
リポジトリーの期限 : 21,600 秒 (最終: Wed Jan 30 01:33:13 2019)
Filter : read-only:present
Repo ファイル名: /etc/yum.repos.d/mongodb-org-4.0.repo
repolist: 30
-
- mongodb-orgパッケージのインストール
-
- yum install -y mongodb-org
-
- mongodb-orgパッケージのインストール 確認
- yum list installed | grep mongodb-org
mongodb-org.x86_64 4.0.5-1.el7 @mongodb-org-4.0
mongodb-org-mongos.x86_64 4.0.5-1.el7 @mongodb-org-4.0
mongodb-org-server.x86_64 4.0.5-1.el7 @mongodb-org-4.0
mongodb-org-shell.x86_64 4.0.5-1.el7 @mongodb-org-4.0
mongodb-org-tools.x86_64 4.0.5-1.el7 @mongodb-org-4.0
-
- mongodbサービス起動
-
- systemctl start mongod
-
- mongodbサービス起動確認
- systemctl status mongod
● mongod.service - MongoDB Database Server
Loaded: loaded (/usr/lib/systemd/system/mongod.service; enabled; vendor preset: disabled)
Active: active (running) since 水 2019-01-30 02:06:26 JST; 1s ago
Docs: https://docs.mongodb.org/manual
Process: 4222 ExecStart=/usr/bin/mongod $OPTIONS (code=exited, status=0/SUCCESS)
Process: 4220 ExecStartPre=/usr/bin/chmod 0755 /var/run/mongodb (code=exited, status=0/SUCCESS)
Process: 4218 ExecStartPre=/usr/bin/chown mongod:mongod /var/run/mongodb (code=exited, status=0/SUCCESS)
Process: 4217 ExecStartPre=/usr/bin/mkdir -p /var/run/mongodb (code=exited, status=0/SUCCESS)
Main PID: 4225 (mongod)
CGroup: /system.slice/mongod.service
└─4225 /usr/bin/mongod -f /etc/mongod.conf
1月 30 02:06:25 localhost.localdomain systemd[1]: Starting MongoDB Database Server...
1月 30 02:06:25 localhost.localdomain mongod[4222]: about to fork child process, wait....
1月 30 02:06:25 localhost.localdomain mongod[4222]: forked process: 4225
1月 30 02:06:26 localhost.localdomain systemd[1]: Started MongoDB Database Server.
Hint: Some lines were ellipsized, use -l to show in full.
设定
如果要控制mongod数据库系统的运行,可以通过命令行或配置文件来进行控制。本文将简要介绍配置文件相关内容。
mongod的配置文件使用YAML格式进行描述。详细信息请参考“Configuration File Options”。另外,配置选项以配置文件为优先。
- サンプル
systemLog:
destination: file
path: "/var/log/mongodb/mongod.log"
logAppend: true
storage:
journal:
enabled: true
processManagement:
fork: true
net:
bindIp: 127.0.0.1
port: 27017
setParameter:
enableLocalhostAuthBypass: false
...
在Mongo Shell中进行数据库操作。Mongo shell 是 MongoDB 的交互式 JavaScript 接口。可以使用 Mongo shell 查询和更新数据,执行管理操作。
创建数据库 – 创建集合
-
mongoシェル起動
-
- mongoシェル起動
-
- mongo
-
- データベースの作成
- use testdb
switched to db testdb
-
- データベースの確認
- show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
在执行 <データベース名> 后,即使进行了一览显示,也无法看到所创建的数据库。至少需要注册一条或更多的数据。在创建集合后,将显示如下所示。
admin 0.000GB
config 0.000GB
local 0.000GB
testdb 0.000GB
举个例子,创建一个名为testcoll的集合,并插入文档。文档可以用JSON格式来描述。
-
- ドキュメントの挿入(コレクションの作成)
-
- db.testcoll.insert( { “key1” : “value1”, “key2” : “value2” } )
ハッシュと配列の混ざったドキュメントの挿入
db.testcoll.insert( { “array” : [ “Windows”, “Mac” , “Linux” ] } )
查阅文件
-
ドキュメントの参照(コレクション全てのデータを取得)
- ドキュメントの参照(コレクション全てのデータを取得)
- db.testcoll.find()
{ "_id" : ObjectId("5c6198f6fb5e83ffaa3ba044"), "key1" : "value1", "key2" : "value2" }
{ "_id" : ObjectId("5c61991ffb5e83ffaa3ba045"), "array" : [ "Windows", "Mac", "Linux" ] }
“_id” : ObjectId(“5c…”) 是MongoDB自动分配的。可以看作是RDBMS中的主键。
-
- ドキュメントの参照(最初の1つのドキュメントを取得)
- db.testcoll.findOne()
{
"_id" : ObjectId("5c6198f6fb5e83ffaa3ba044"),
"key1" : "value1",
"key2" : "value2"
}
-
- ドキュメントの参照(ハッシュキーを引数に渡して値を取得)
- db.testcoll.findOne()[“key1”]
value1
-
- コレクションの確認
- show collections
testcoll
用Javascript进行数据库操作
-
ドキュメントの挿入(forループでデータを挿入)
- ドキュメントの挿入(forループでデータを挿入)
-
- for (let i = 1; i <= 10; i++) db.testcoll2.insert( { x : 1 , y : i } )
-
- 検索結果に対するカーソル
-
- var c = db.testcoll2.find()
- while ( c.hasNext() ) printjson( c.next() )
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba046"), "x" : 1, "y" : 1 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba047"), "x" : 1, "y" : 2 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba048"), "x" : 1, "y" : 3 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba049"), "x" : 1, "y" : 4 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04a"), "x" : 1, "y" : 5 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04b"), "x" : 1, "y" : 6 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04c"), "x" : 1, "y" : 7 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04d"), "x" : 1, "y" : 8 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04e"), "x" : 1, "y" : 9 }
{ "_id" : ObjectId("5c6199aefb5e83ffaa3ba04f"), "x" : 1, "y" : 10 }
-
- ドキュメントを変数に格納
-
- doc=db.testcoll2.findOne()
キー”key1″の値を表示
printjson(doc[“x”])
1
有关MongoDB的CRUD操作的详细信息,请参考MongoDB CRUD操作。
关闭数据库连接Mongo Shell时,可以使用以下命令来终止服务。
使用管理员
switched to db admin
关闭数据库服务器。
server should be down...
2019-02-12T00:53:59.058+0900 I NETWORK [js] trying reconnect to 127.0.0.1:27017 failed
2019-02-12T00:53:59.058+0900 I NETWORK [js] reconnect 127.0.0.1:27017 failed failed
退出();
MongoDB启动失败如果启动mongod失败,可能是由于使用了强制结束等方法导致锁定文件未被清除。
● mongod.service - MongoDB Database Server
Loaded: loaded (/usr/lib/systemd/system/mongod.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since 月 2019-02-11 23:47:18 JST; 47min ago
Docs: https://docs.mongodb.org/manual
Process: 3190 ExecStart=/usr/bin/mongod $OPTIONS (code=exited, status=14)
Process: 3185 ExecStartPre=/usr/bin/chmod 0755 /var/run/mongodb (code=exited, status=0/SUCCESS)
Process: 3181 ExecStartPre=/usr/bin/chown mongod:mongod /var/run/mongodb (code=exited, status=0/SUCCESS)
Process: 3176 ExecStartPre=/usr/bin/mkdir -p /var/run/mongodb (code=exited, status=0/SUCCESS)
2月 11 23:47:06 localhost.localdomain systemd[1]: Starting MongoDB Database Server...
2月 11 23:47:10 localhost.localdomain mongod[3190]: about to fork child process, wait....
2月 11 23:47:10 localhost.localdomain mongod[3190]: forked process: 3461
2月 11 23:47:18 localhost.localdomain systemd[1]: mongod.service: control process exi...4
2月 11 23:47:18 localhost.localdomain systemd[1]: Failed to start MongoDB Database Se....
2月 11 23:47:18 localhost.localdomain systemd[1]: Unit mongod.service entered failed ....
2月 11 23:47:18 localhost.localdomain systemd[1]: mongod.service failed.
Hint: Some lines were ellipsized, use -l to show in full.
● mongod.service - MongoDB Database Server
Loaded: loaded (/usr/lib/systemd/system/mongod.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since 月 2019-02-11 23:47:18 JST; 47min ago
Docs: https://docs.mongodb.org/manual
Process: 3190 ExecStart=/usr/bin/mongod $OPTIONS (code=exited, status=14)
Process: 3185 ExecStartPre=/usr/bin/chmod 0755 /var/run/mongodb (code=exited, status=0/SUCCESS)
Process: 3181 ExecStartPre=/usr/bin/chown mongod:mongod /var/run/mongodb (code=exited, status=0/SUCCESS)
Process: 3176 ExecStartPre=/usr/bin/mkdir -p /var/run/mongodb (code=exited, status=0/SUCCESS)
2月 11 23:47:06 localhost.localdomain systemd[1]: Starting MongoDB Database Server...
2月 11 23:47:10 localhost.localdomain mongod[3190]: about to fork child process, wait....
2月 11 23:47:10 localhost.localdomain mongod[3190]: forked process: 3461
2月 11 23:47:18 localhost.localdomain systemd[1]: mongod.service: control process exi...4
2月 11 23:47:18 localhost.localdomain systemd[1]: Failed to start MongoDB Database Se....
2月 11 23:47:18 localhost.localdomain systemd[1]: Unit mongod.service entered failed ....
2月 11 23:47:18 localhost.localdomain systemd[1]: mongod.service failed.
Hint: Some lines were ellipsized, use -l to show in full.
如果是这种情况,执行以下命令并删除锁定文件,即可成功启动。
删除 /var/lib/mongo/mongod.lock
删除 /tmp/mongodb-27017.sock
如果/var/log/mongodb/mongod.log的日志中出现如下所示的“715: /var/lib/mongo/WiredTiger.turtle: handle-open: open: Permission denied”的记录,请检查/var/lib/mongo目录的权限。
2019-02-12T01:10:04.498+0900 E STORAGE [initandlisten] WiredTiger error (13) [1549901404:498011][3521:0x7f0ba3f22b80], wiredtiger_open: __posix_open_file, 715: /var/lib/mongo/WiredTiger.turtle: handle-open: open: Permission denied Raw: [1549901404:498011][3521:0x7f0ba3f22b80], wiredtiger_open: __posix_open_file, 715: /var/lib/mongo/WiredTiger.turtle: handle-open: open: Permission denied
使用 MongoDB 进行备份MongoDB的备份对象包括数据本身的备份和配置选项的备份。
对于配置选项,只需复制mongod启动shell或配置文件等文件即可。
另外,一般情况下,在数据备份过程中会使用完全备份和增量备份的组合方式,但是MongoDB并没有增量备份的功能。
MongoDB的备份方法
在MongoDB中,进行全备份有两种方法:
-
データファイルをコピーする方法
- データファイルをコピーする方法
-
- データベースを停止するか、ロックしておく必要がある
-
- mongodumpを利用する方法
- mongodumpデータベースの内容のバイナリエクスポートを作成するためのユーティリティ。mongodumpの場合、オンラインバックアップが可能
请注意以下事项:
由于索引在恢复过程中不会被转储,因此如果存在较大的索引,恢复的时间会较长。此外,虽然适用于备份和恢复小规模MongoDB部署的简单高效工具,但并不适用于获取大型系统的备份是理想的选择。
使用mongodump进行备份
-
バックアップ
- バックアップ
- mongodump
2019-02-12T01:28:20.371+0900 writing admin.system.version to
2019-02-12T01:28:20.372+0900 done dumping admin.system.version (1 document)
2019-02-12T01:28:20.372+0900 writing testdb.testcoll2 to
2019-02-12T01:28:20.372+0900 writing testdb.testcoll to
2019-02-12T01:28:20.379+0900 done dumping testdb.testcoll (2 documents)
2019-02-12T01:28:20.380+0900 done dumping testdb.testcoll2 (10 documents)
执行mongodump命令后,将在当前目录中创建一个名为dump的文件夹。该dump文件夹中存放着数据库的集合等数据的备份。
[root@localhost tmp]# ll dump/
合計 0
drwxr-xr-x. 2 root root 69 2月 12 01:28 admin
drwxr-xr-x. 2 root root 110 2月 12 01:28 testdb
使用mongodump进行恢复操作让我们试一试,在进行恢复之前删除之前创建的数据,然后确认数据是否恢复成功。
首先,我们分别删除testcoll和testcoll2这两个集合作为示例。
-
コレクションの削除
- コレクションの削除
-
- db.testcoll.drop();
- db.testcoll2.drop();
我成功删除了集合,但数据库未能被删除,因此我也会删除数据库。
-
- データベースの削除
- db.dropDatabase();
{ "dropped" : "testdb", "ok" : 1 }
由于可以删除数据库,因此我们将进行恢复。
-
- リストア
- mongorestore ./dump
2019-02-12T03:32:42.592+0900 preparing collections to restore from
2019-02-12T03:32:42.594+0900 reading metadata for testdb.testcoll2 from dump/testdb/testcoll2.metadata.json
2019-02-12T03:32:42.608+0900 restoring testdb.testcoll2 from dump/testdb/testcoll2.bson
2019-02-12T03:32:42.611+0900 reading metadata for testdb.testcoll from dump/testdb/testcoll.metadata.json
2019-02-12T03:32:42.611+0900 no indexes to restore
2019-02-12T03:32:42.611+0900 finished restoring testdb.testcoll2 (10 documents)
2019-02-12T03:32:42.624+0900 restoring testdb.testcoll from dump/testdb/testcoll.bson
2019-02-12T03:32:42.627+0900 no indexes to restore
2019-02-12T03:32:42.627+0900 finished restoring testdb.testcoll (2 documents)
2019-02-12T03:32:42.627+0900 done
在执行还原操作后,连接到mongo shell以确认是否已经成功还原。
展示数据库
admin 0.000GB
config 0.000GB
local 0.000GB
testdb 0.000GB
展示集合
testcoll
testcoll2
在数据库中查找testcoll。
{ "_id" : ObjectId("5c6198f6fb5e83ffaa3ba044"), "key1" : "value1", "key2" : "value2" }
{ "_id" : ObjectId("5c61991ffb5e83ffaa3ba045"), "array" : [ "Windows", "Mac", "Linux" ] }
确认数据库、集合和文档已成功恢复。
监视
以下是有关监视mongod的命令:
-
コレクションの処理時間順に表示
- コレクションの処理時間順に表示
- mongotop
2019-02-12T01:34:41.789+0900 connected to: 127.0.0.1
ns total read write 2019-02-12T01:34:42+09:00
admin.system.roles 0ms 0ms 0ms
admin.system.version 0ms 0ms 0ms
config.system.sessions 0ms 0ms 0ms
local.startup_log 0ms 0ms 0ms
local.system.replset 0ms 0ms 0ms
testdb.testcoll 0ms 0ms 0ms
testdb.testcoll2 0ms 0ms 0ms
-
- MongoDB全体の状態を表示
- mongostat
time
*0 *0 *0 *0 0 2|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 158b 62.4k 1 Feb 12 01:35:25.188
*0 *0 *0 *0 0 1|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 157b 62.2k 1 Feb 12 01:35:26.188
*0 *0 *0 *0 0 1|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 157b 62.1k 1 Feb 12 01:35:27.190
*0 *0 *0 *0 0 2|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 158b 62.4k 1 Feb 12 01:35:28.187
*0 *0 *0 *0 0 1|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 157b 62.2k 1 Feb 12 01:35:29.187
*0 *0 *0 *0 0 1|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 157b 62.2k 1 Feb 12 01:35:30.188
*0 *0 *0 *0 0 2|0 0.0% 0.0% 0 1.06G 49.0M 0|0 1|0 158b 62.2k 1 Feb 12 01:35:31.187
-
- MongoDB全体の統計情報(serverStatus()メソッド)
- db.serverStatus()
{
"host" : "localhost.localdomain",
"version" : "4.0.5",
"process" : "mongod",
"pid" : NumberLong(3718),
"uptime" : 5961,
"uptimeMillis" : NumberLong(5961613),
"uptimeEstimate" : NumberLong(5961),
"localTime" : ISODate("2019-02-15T18:04:20.956Z"),
"asserts" : {
"regular" : 0,
"warning" : 0,
"msg" : 0,
"user" : 2,
"rollovers" : 0
},
"connections" : {
"current" : 1,
"available" : 51199,
"totalCreated" : 4
...
日志从版本3.0.0的新功能中,加上–logRotate reopen选项,可以按照典型的Linux/Unix日志轮换行为来打开日志文件。
首先,在/etc/mongod.conf文件中写入配置值”logRotate: reopen”,以描述MongoDB的日志轮转方法。
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
logRotate: reopen
接下来,我们将在/etc/logrotate.d/目录下为mongod创建一个日志轮换的配置文件。
打开 /etc/logrotate.d/mongod 文件进行编辑。
/var/log/mongodb/mongod.log {
daily
rotate 30
missingok
compress
delaycompress
notifempty
create 640 mongod mongod
sharedscripts
postrotate
/bin/kill -SIGUSR1 `cat /var/run/mongodb/mongod.pid 2>/dev/null` >/dev/null 2>&1
endscript
}
进行日志轮换测试,请执行以下命令:
logrotate -dv /etc/logrotate.d/mongod
reading config file /etc/logrotate.d/mongod
Allocating hash table for state file, size 15360 B
Handling 1 logs
rotating pattern: /var/log/mongodb/mongod.log after 1 days (30 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/mongodb/mongod.log
log does not need rotating (log has been already rotated)not running postrotate script, since no logs were rotated
当确认没有输出错误后,logrotate将自动执行日志轮换。
-rw-r-----. 1 mongod mongod 1385 2月 16 01:38 /var/log/mongodb/mongod.log
-rw-------. 1 mongod mongod 115166 2月 16 01:38 /var/log/mongodb/mongod.log.1
另外,在mongo shell连接时,您还可以使用以下命令手动进行日志轮转:
db.adminCommand( { logRotate:1 } )
{ "ok" : 1 }
创建用户
启用认证功能,并对数据库进行用户级别的访问控制。
首先,在连接Mongo shell时,执行以下命令以创建管理员用户。
使用管理者
db.createUser(
{
user: "admin",
pwd: "password",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
Successfully added user: {
"user" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
用户信息被保存在admin数据库中。而且,用户信息也存储在admin数据库的system.users集合中。
在用户管理中,有两种角色,分别是userAdmin与userAdminAnyDatabase。userAdmin是一种内置角色,仅可用于指定的数据库进行用户管理。而userAdminAnyDatabase是一种特殊的内置角色,只能用于admin数据库,并赋予了该角色的用户可以进行所有数据库的用户管理。
接下来,创建一个常规用户。使用 testdb。
db.createUser(
{
user: "testuser",
pwd: "password",
roles: [ { role: "readWrite", db: "testdb" } ]
}
)
Successfully added user: {
"user" : "testuser",
"roles" : [
{
"role" : "readWrite",
"db" : "testdb"
}
]
}
确认用户已创建。
使用管理员账户。
在系统用户中查找。
{ "_id" : "admin.admin", "user" : "admin", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "mBaj6lY+FmjRpDoXAq/9nA==", "storedKey" : "/zqpTgZEV2iUlFsXwybT7t2NeYI=", "serverKey" : "+m4wf2orLVRyntSJTLjbIsa23+Q=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "leY10lhgYGZHVm3FdcDqIKVig4ZSegW8lYBDzA==", "storedKey" : "gwSafO6sc4OqJTWJ2aJcYXQ4XnxdZFEYR4Bv4aGjyas=", "serverKey" : "n8D7GZboYIpkJf++35GXENDK8ubSWiksu23+OFNXcGE=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }
{ "_id" : "admin.testuser", "user" : "testuser", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "EVUclTLqMCIn1jtYqNBjWQ==", "storedKey" : "HQ1HiqS4FTMuVSH4wYuFPYMHBfI=", "serverKey" : "kQZPAh6kNqRlqoglY3k7D1864n8=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "KjnGdFe2WrAb5xhXdoAL25okfrc00uU1xI7Oow==", "storedKey" : "ZRUhnJPJrQBdgq94qcrRFOglQ3SgO/o5By5mKMKHMIk=", "serverKey" : "2N9s8GJLT7Q9dVT4Q33r/QehPK9H+ThgwK4EwQTvCWE=" } }, "roles" : [ { "role" : "readWrite", "db" : "testdb" } ] }
启用用户认证功能。
vi /etc/mongod.conf
security:
authorization: enabled
进行服务重启后,等待配置生效,连接到Mongo Shell并执行以下命令,确认身份验证功能已启用。
使用管理员身份查询数据库中的用户,命令为db.system.user.find()。
Error: error: {
"ok" : 0,
"errmsg" : "command find requires authentication",
"code" : 13,
"codeName" : "Unauthorized"
}
由于启用了身份验证功能,会输出错误信息,因此需要进行身份验证。
db.auth(“admin”,”password”)
1
再次执行命令,您可以确认用户信息。db.system.users.find()。
{ "_id" : "admin.admin", "user" : "admin", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "mBaj6lY+FmjRpDoXAq/9nA==", "storedKey" : "/zqpTgZEV2iUlFsXwybT7t2NeYI=", "serverKey" : "+m4wf2orLVRyntSJTLjbIsa23+Q=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "leY10lhgYGZHVm3FdcDqIKVig4ZSegW8lYBDzA==", "storedKey" : "gwSafO6sc4OqJTWJ2aJcYXQ4XnxdZFEYR4Bv4aGjyas=", "serverKey" : "n8D7GZboYIpkJf++35GXENDK8ubSWiksu23+OFNXcGE=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }
{ "_id" : "admin.testuser", "user" : "testuser", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "EVUclTLqMCIn1jtYqNBjWQ==", "storedKey" : "HQ1HiqS4FTMuVSH4wYuFPYMHBfI=", "serverKey" : "kQZPAh6kNqRlqoglY3k7D1864n8=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "KjnGdFe2WrAb5xhXdoAL25okfrc00uU1xI7Oow==", "storedKey" : "ZRUhnJPJrQBdgq94qcrRFOglQ3SgO/o5By5mKMKHMIk=", "serverKey" : "2N9s8GJLT7Q9dVT4Q33r/QehPK9H+ThgwK4EwQTvCWE=" } }, "roles" : [ { "role" : "readWrite", "db" : "testdb" } ] }
进行调查以下是MongoDB设计时的注意事项。
-
性能
- 性能
シャーディングをしっかり組むこと
ドキュメント肥大化によりドキュメントの再配置が起こらないように、ドキュメントに必要なフィールドをあらかじめ作っておく
ジャーナルの書き込み回数を減らす
オンメモリを考慮し、全データをアクセスするような処理は行わない
運用
ハードウェア障害に備えて、バックアップファイルは別のサーバ上に退避させる
ディスク使用率やメモリ使用率のしきい値監視
クラウドの場合、DC被災時を考慮してレプリカセットを構築しておけば、DR切替が容易。
セキュリティ
デフォルトポートからの変更
クエリログの出力
データベースに対する外部からのアクセス制限及び認証
ディスク暗号化あるいは、データベースレイヤーでの暗号化(性能とトレードオフ)
请参考Welcome to the MongoDB Docs
The MongoDB 4.0 Manual
Install MongoDB Community Edition on Red Hat Enterprise or CentOS Linux
MongoDBの薄い本
MongoDBを始めた頃に知っていたら、と思う14のこと
Automating MongoDB Log Rotation