Mongodb安装及性能测试
1. MongoDB介绍
MongoDB是一个开源的、基于分布式文件存储的NoSQL数据库系统。它使用文档存储方式,数据结构由键值(key-value)对组成,与传统的关系型数据库不同,MongoDB的文档模型具有灵活的模式(schema),这使得它非常适合处理复杂的数据结构。MongoDB支持自动分片(sharding)和复制集(replica set),从而实现高可用性和可扩展性。
2. MongoDB安装
MongoDB可以在多种操作系统上安装,包括Linux、macOS和Windows。
2.1 CentOS下安装
下面记录CentOS7下安装MongoDB4.0:
# 添加yum源
$ cd /etc/yum.repos.d/
$ sudo vi mongodb.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
# 安装Mongodb
$ sudo yum makecache
$ sudo yum install mongodb-org
此命令将安装mongodb-org,包含以下内容:
- mongodb-org-server: 标准的MongoDB服务端程序(既守护程序),以及相应的init脚本和配置
- mongodb-org-mongos: MongoDB Shard集群服务端程序(守护进程)
- mongodb-org-shell: MongoDB shell,用于通过命令行与MongoDB交互
- mongodb-org-tools: 包含一些用于恢复,导入和导出数据的基本工具,以及其他各种功能
启动并设置开机自启动:
$ sudo systemctl start mongod
$ sudo systemctl enable mongod
$ sudo systemctl status mongod
2.2 Ubuntu下安装
- 导入公共GPG密钥
wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | sudo apt-key add -
- 创建MongoDB源列表文件
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu $(lsb_release -cs)/mongodb-org/6.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list
- 更新包列表
sudo apt-get update
- 安装MongoDB
sudo apt-get install -y mongodb-org
- 启动MongoDB服务
sudo systemctl start mongod
- 设置MongoDB在系统启动时自动启动
sudo systemctl enable mongod
2.3 macOS下安装
- 使用Homebrew安装
brew tap mongodb/brew
brew install mongodb-community@6.0
- 启动MongoDB服务
brew services start mongodb/brew/mongodb-community
2.4 在Windows上安装MongoDB
-
下载MongoDB:从MongoDB官方网站下载最新的MongoDB安装包。
-
运行安装程序:按照安装向导的指示进行安装,选择“Complete”安装。
-
配置MongoDB:完成安装后,可以通过命令行启动MongoDB服务
"C:\Program Files\MongoDB\Server\6.0\bin\mongod.exe" --dbpath="C:\data\db"
2. 配置MongoDB
2.1 开启访问控制
以CentOS环境下为例,配置文件位于/etc/mongod.conf
,YAML格式,根据需求按需修改。其中security修改如下,启用基于角色的访问控制:
security:
authorization: enabled
每次修改配置文件后需要重启mongod
服务。
2.2 修改用户限制
sudo vi /etc/security/limits.conf
# 加入如下内容
mongod soft nofiles 64000
mongod soft nproc 64000
2.3 创建测试的数据库和用户
默认情况下,MongoDB 是没有管理员账户的,当开启认证后需要在 admin 数据库
中使用 db.createUser()
命令添加管理员帐号或其他角色。
# 打开mongo shell
$ mongo
# 创建管理员账号
> use admin
switched to db admin
> db.createUser({user: "admin", pwd: "123456", roles:[{role: "userAdminAnyDatabase", db: "admin"}]})
Successfully added user: {
"user" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
> db.auth("admin", "123456")
1
> exit
# 测试连接
$ mongo -u admin -p --authenticationDatabase admin
> use admin
> show tables
system.users
system.version
# 创建测试数据库和用户
> use testdb
> db.createUser({user:'test',pwd:'123456',roles:[{role:'readWrite',db:'testdb'}]})
可以使用:mongodb://youruser:yourpassword@localhost/yourdatabase
来连接到你的mongo。
添加用户时各个角色对应权限:
- 数据库用户角色:read、readWrite;
- 数据库管理角色:dbAdmin、dbOwner、userAdmin;
- 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
- 备份恢复角色:backup、restore
- 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
- 超级用户角色:root
2.4 mongodb常用命令
数据库操作命令
命令 | 说明 |
---|---|
show dbs | 显示所有数据库 |
use <database_name> | 切换或创建数据库 |
db | 显示当前数据库 |
db.dropDatabase() | 删除当前数据库 |
show collections | 显示当前数据库的所有集合 |
集合管理命令
命令 | 说明 |
---|---|
db.createCollection('<name>') | 创建集合 |
db.<collection_name>.drop() | 删除集合 |
db.<collection_name>.renameCollection('<new_name>') | 重命名集合 |
db.<collection_name>.stats() | 获取集合的统计信息 |
用户管理命令
命令 | 说明 |
---|---|
db.createUser({user: ..., pwd: ..., roles: [...]}) | 创建新用户 |
db.dropUser('<username>') | 删除用户 |
db.updateUser('<username>', {...}) | 更新用户信息 |
db.grantRolesToUser('<username>', [...]) | 向用户授予角色 |
db.revokeRolesFromUser('<username>', [...]) | 从用户撤销角色 |
db.getUsers() | 获取所有用户的信息 |
db.getUser('<username>') | 获取单个用户的信息 |
索引管理命令
命令 | 说明 |
---|---|
db.<collection_name>.createIndex({...}) | 为集合创建索引 |
db.<collection_name>.dropIndex('<index_name>') | 删除索引 |
db.<collection_name>.getIndexes() | 获取集合的所有索引 |
db.<collection_name>.reIndex() | 重新索引集合 |
复制集管理命令
命令 | 说明 |
---|---|
rs.initiate() | 初始化一个新的复制集 |
rs.reconfig({...}) | 重新配置复制集 |
rs.status() | 获取复制集的状态 |
rs.add('<hostname>') | 向复制集中添加成员 |
rs.remove('<hostname>') | 从复制集中移除成员 |
分片管理命令
命令 | 说明 |
---|---|
sh.enableSharding('<database>') | 为数据库启用分片 |
sh.shardCollection('<database>.<collection>', {key: 1}) | 为集合启用分片 |
sh.addShard('<hostname>') | 添加新的分片 |
sh.removeShard('<hostname>') | 移除分片 |
sh.status() | 查看分片状态 |
备份与恢复命令(使用外部工具)
命令 | 说明 |
---|---|
mongodump | 备份数据库 |
mongorestore | 从备份恢复数据库 |
这些命令帮助你在MongoDB中管理数据库和集合,从创建到删除、用户管理、索引管理、复制集管理和分片管理,涵盖了数据库生命周期的各个方面【56†source】【57†source】。
3. MongoDB性能测试方案
为了测试MongoDB的性能,可以使用第三方工具如YCSB(Yahoo! Cloud Serving Benchmark)
。YCSB是一个Java语言实现的用于云端或者服务器端的数据库性能测试工具,其内部涵盖了常见的NoSQL数据库产品,如Cassandra、MongoDB、HBase、Redis等等。
这个框架具有很好的可扩展性,可以通过配置文件来指定需要进行什么样的workload的测试,比如读写比例多少,每条记录多大,每个字段多大,并发数多大,进行随机选择使用的分布(比如读一条数据的时候)等。
备注:
工具依赖java,请确认已经安装java运行环境。
二进制下载安装:
$ wget https://github.com/brianfrankcooper/YCSB/releases/download/0.17.0/ycsb-mongodb-binding-0.17.0.tar.gz
$ tar xf ycsb-mongodb-binding-0.17.0.tar.gz
$ sudo chown -R mongod:mongod ycsb-mongodb-binding-0.17.0
源码编译安装:
$ git clone https://github.com/brianfrankcooper/YCSB.git
$ cd YCSB
$ mvn clean package
默认的6种测试场景如下:
1)workloada:读写均衡型,50%/50%,Reads/Writes
2)workloadb:读多写少型,95%/5%,Reads/Writes
3)workloadc:只读型,100%,Reads
4)workloadd:读最近写入记录型,95%/5%,Reads/insert
5)workloade:扫描小区间型,95%/5%,scan/insert
6)workloadf:读写入记录均衡型,50%/50%,Reads/insert
压测数据:
# 加载100W条数据,每条数据5个字段,数据长度2048。加载完后数据大小大约10GB,耗时5分钟,可以在 load_result.txt文件查看执行结果,主要用来查看执行失败时的错误。
$ sudo ./bin/ycsb load mongodb -s -P ./workloads/workloada -threads 100 -p insertstart=0 -p recordcount=1000000 -p readproportion=0 -p updateproportion=0 -p insertproportion=1 -p fieldcount=5 -p fieldlength=2048 -p requestdistribution=uniform -p mongodb.url=mongodb://testdbadmin:password@127.0.0.1:27017/testdb -p table=t1
# 加载结果
mongo client connection created with mongodb://testdbadmin:password@127.0.0.1:27017/testdb
[OVERALL], RunTime(ms), 614831
[OVERALL], Throughput(ops/sec), 1626.4632069625636
[TOTAL_GCS_PS_Scavenge], Count, 140
[TOTAL_GC_TIME_PS_Scavenge], Time(ms), 715
[TOTAL_GC_TIME_%_PS_Scavenge], Time(%), 0.11629211929782332
[TOTAL_GCS_PS_MarkSweep], Count, 0
[TOTAL_GC_TIME_PS_MarkSweep], Time(ms), 0
[TOTAL_GC_TIME_%_PS_MarkSweep], Time(%), 0.0
[TOTAL_GCs], Count, 140
[TOTAL_GC_TIME], Time(ms), 715
[TOTAL_GC_TIME_%], Time(%), 0.11629211929782332
[CLEANUP], Operations, 100
[CLEANUP], AverageLatency(us), 34.78
[CLEANUP], MinLatency(us), 0
[CLEANUP], MaxLatency(us), 3295
[CLEANUP], 95thPercentileLatency(us), 3
[CLEANUP], 99thPercentileLatency(us), 15
[INSERT], Operations, 1000000
[INSERT], AverageLatency(us), 60102.254371
[INSERT], MinLatency(us), 120
[INSERT], MaxLatency(us), 19267583
[INSERT], 95thPercentileLatency(us), 16183
[INSERT], 99thPercentileLatency(us), 100863
[INSERT], Return=OK, 1000000
执行测试:
$ sudo ./bin/ycsb run mongodb -s -P ./workloads/workloada -threads 100 -p recordcount=1000000 -p operationcount=1000000 -p insertstart=0 -p insertcount=0 -p readproportion=0.95 -p updateproportion=0.05 -p insertproportion=0 -p fieldcount=5 -p fieldlength=2048 -p mongodb.url=mongodb://testdbadmin:password@127.0.0.1:27017/testdb -p table=t1
# 测试结果
[OVERALL], RunTime(ms), 67711
[OVERALL], Throughput(ops/sec), 14768.649111665756
[TOTAL_GCS_PS_Scavenge], Count, 123
[TOTAL_GC_TIME_PS_Scavenge], Time(ms), 558
[TOTAL_GC_TIME_%_PS_Scavenge], Time(%), 0.8240906204309493
[TOTAL_GCS_PS_MarkSweep], Count, 0
[TOTAL_GC_TIME_PS_MarkSweep], Time(ms), 0
[TOTAL_GC_TIME_%_PS_MarkSweep], Time(%), 0.0
[TOTAL_GCs], Count, 123
[TOTAL_GC_TIME], Time(ms), 558
[TOTAL_GC_TIME_%], Time(%), 0.8240906204309493
[READ], Operations, 949957
[READ], AverageLatency(us), 6626.8172759398585
[READ], MinLatency(us), 102
[READ], MaxLatency(us), 4689919
[READ], 95thPercentileLatency(us), 11143
[READ], 99thPercentileLatency(us), 54175
[READ], Return=OK, 949957
[CLEANUP], Operations, 100
[CLEANUP], AverageLatency(us), 34.37
[CLEANUP], MinLatency(us), 1
[CLEANUP], MaxLatency(us), 3225
[CLEANUP], 95thPercentileLatency(us), 3
[CLEANUP], 99thPercentileLatency(us), 13
[UPDATE], Operations, 50043
[UPDATE], AverageLatency(us), 7140.278580420838
[UPDATE], MinLatency(us), 167
[UPDATE], MaxLatency(us), 4349951
[UPDATE], 95thPercentileLatency(us), 12863
[UPDATE], 99thPercentileLatency(us), 62879
[UPDATE], Return=OK, 50043
备注:
- 执行过程中的如下错误可以忽略:
DBWrapper: report latency for each error is false and specific error codes to track for latency are: []
- 如果重新执行测试,需要在mongodb中删除测试的数据库。
4. 优化MongoDB性能的建议
-
索引优化:确保为常用查询建立合适的索引,但避免过多的索引,因为这会影响写性能。
-
硬件优化:使用SSD存储,增加内存以确保更多的工作集可以放在内存中。
-
分片(Sharding):对于大规模数据集,使用分片来分布数据和负载。
-
复制集(Replica Set):配置复制集来提高数据的可用性和读取性能。
-
读写分离:在复制集中,使用辅助节点(secondary nodes)处理只读请求,以减轻主节点(primary node)的负担。
-
数据库配置:调整MongoDB配置文件
mongod.conf
中的参数,如wiredTigerCacheSizeGB
,根据可用内存进行调整。
通过合理的配置和优化,可以显著提升MongoDB的性能,满足高并发、低延迟的数据处理需求。