分布式存储 - MongoDB

MongoDB是基于文档存储的,文档存储一般用类似 json 的格式存储,存储的内容是文档型的,这样也就有机会对某些字段建立索引,实现关系数据库的某些功能。

MongoDB 安装

单机模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.11.tgz
$ tar -zxvf mongodb-linux-x86_64-4.0.11.tgz
$ mv mongodb-linux-x86_64-4.0.11 /usr/local/mongodb
$ cd /usr/local/mongodb

$ mkdir conf data logs
$ vi conf/mongod.yaml

# https://docs.mongodb.com/manual/reference/configuration-options/
storage:
dbPath: /usr/local/mongodb/data
systemLog:
destination: file
path: /usr/local/mongodb/logs/mongod.log
net:
port: 27017
# 允许远程访问(默认值为localhost即只能本地访问)
bindIp: 0.0.0.0

## 启动服务
$ ./bin/mongod --config conf/mongod.yaml
## 测试
$ ./bin/mongo --host 192.168.8.128 --port 27017

集群模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
## MongoDB replica-set cluster

## 在集群的服务器上分别启动服务
$ ./bin/mongod --config /usr/local/mongodb/conf/mongod.yaml --replSet rs0

## 连接到其中一台服务器上创建replica-set集群
$ ./bin/mongo --host 192.168.8.128 --port 27017

> rs.initiate({_id: 'rs0', members: [
{_id: 0, host: '192.168.8.128:27017'},
{_id: 1, host: '192.168.8.129:27017'},
{_id: 2, host: '192.168.8.130:27017'}
]})
> rs.status()

MongoDB 相关概念

SQL术语/概念 MongoDB术语/概念 解释/说明
database database 数据库
table collection 数据库表 / 集合
row document 数据记录行 / 文档
column field 数据字段 / 域
index index 索引
table joins 表连接 / MongoDB不支持
primary key primary key 主键 / MongoDB自动将_id字段设置为主键

MongoDB集默认会创建admin、local、config数据库:admin数据库则主要存储MongoDB的用户、角色等信息;local数据库主要存储副本集的元数据;config 数据库在内部使用,当使用分片模式时,用于保存分片的信息。

MongoDB 事务支持

在 MongoDB 4.0 之前的版本中,操作单个文档是原子性的,但操作多文档是非原子性的;从 MongoDB 4.0 版本开始支持多文档 ACID 事务,但多文档事务仅适用于副本集。

1
2
3
4
5
spring:
data:
mongodb:
# Mongo supports transaction feature for a replica set
uri: mongodb://192.168.8.128:27017,192.168.8.129:27017,192.168.8.130:27017/test?replicaSet=rs0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration
public class MongoConfig {

/**
* Remove {@link DefaultMongoTypeMapper#DEFAULT_TYPE_KEY} Field
*/
public MongoConfig(MappingMongoConverter mappingMongoConverter) {
mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
}

@Bean
MongoTransactionManager transactionManager(MongoDbFactory dbFactory) {
return new MongoTransactionManager(dbFactory);
}

}

MongoDB 常用命令

命令 描述
show dbs 显示所有数据库
use [database_name] 如果数据库不存在则创建,否则切换到指定数据库
db.dropDatabase() 删除当前使用的数据库(db代表当前使用的数据库)
db 查看当前使用的数据库
show collections 查看当前数据库中的所有集合
db.createCollection(name) 在当前数据库中创建集合
db.getCollection(name).drop() 在当前数据库中删除集合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
db.createCollection("distlock");
db.getCollection("distlock").insert({
_id: NumberLong("604797950328573952"),
methodName: "createOrder",
updatedAt: new Date()
});
db.getCollection("distlock").update({
_id: NumberLong("604797950328573952")
}, {
methodName: "createPayOrder",
updatedAt: new Date()
});
db.getCollection("distlock").find({
methodName: "createPayOrder"
});
db.getCollection("distlock").drop();

注意: 在 MongoDB 中,集合只有在内容插入后才会创建,即创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建;但 spring-data-mongodb 不支持自动创建Collection集合,故需要手动先创建Collection集合,否则会抛出 Cannot create namespace xxx.xxx in multi-document transaction 错误。

MongoDB 适用场景

  • 应用不需要事务及复杂join支持
  • 新应用,需求会变,数据模型无法确定,想快速迭代开发
  • 应用需要2000~3000以上的读写QPS
  • 应用需要TB甚至PB级别数据存储
  • 应用发展迅速,需要能快速水平扩展
  • 应用要求存储的数据不丢失
  • 应用需要99.999%高可用
  • 应用需要大量的地理位置查询、文本查询