本文目标是快速搭建一套 mongodb 的环境,实现在服务器端运行 mongodb,客户端通过网络访问 mongodb。服务器上用 docker 来运行 mongodb,客户端用 pymongo 来连接和访问 mongodb

本文目标不是深入研究 mongodb 的技术细节,而在于快速搭建一个工具,帮助后续数据分析。本文分三方面介绍:

  • 服务器上用 docker 安装配置 mongodb
  • 客户端用 pymongo 连接 mongodb
  • mongodb 的备份与恢复

1. 服务器安装配置 mongodb

1.1 服务器上 docker 配置

用 docker 来安装配置 mongodb,可以省去繁琐 mongodb 配置,也不会搞坏本地环境。可以查看 docker 官方网站获取安装指南,或者查看这篇文章。为提升 docker 来运行 mongodb 的体验,建议如下配置 docker:

  1. 配置国内镜像源(这里用中科大的源)

    修改配置文件 /etc/docker/daemon.json,新增:

    {
      "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn/"]
    }
  2. 配置 docker 非 root 用户运行

    1. 创建一个 docker 用户组
    2. 将当前用户加入 docker 这个组

1.2 运行 mongodb 容器

服务器上获取 mongodb 镜像:

docker pull mongo

启动镜像(命名为 LearnMongo),注意如下规则:

  1. 端口转发 mongodb 服务默认使用端口 27017,docker 运行时需要将此端口暴露到 host 机器
  2. 存储位置 mongodb 会存储到 /data/db,docker 运行时候需要文件夹映射

整体启动命令如下:

docker run --name LearnMongo -d -v $HOME/.LearnMongo:/data/db -p 27017:27017 mongo

通过 docker 命令查看 container 是否启动起来:

docker container ls -a | grep LearnMongo

如果有输出,则是正常运行起来;如果没有,则需要检查 docker 是否正常运行。

客户端的机器上,可以检查服务器相关端口,来确保连接是否通畅:

curl localhost:27017
# It looks like you are trying to access mongodb over HTTP on the native driver port.

如果客户端上没有这个输出,需要检查服务器防火墙是否打开相关端口。

2. 客户端连接 mongodb

mongoshmongodb 的连接工具,实际使用起来并不方便;通常 python 实现的 pymongo 访问起来就比较方便。

2.1 pymongo 连接 mongodb

客户端上安装 pymongo

python3 -m pip install --user --upgrade pymongo

pymongo 来连接客户端,需要一个 client

def get_client(host="", port="", account=None, password=None):
    login_kwargs = dict(host=host, port=port)
    if account:
        assert password is not None
        print("login with account and password")
        login_kwargs.update(dict(account=account, password=password))
    return MongoClient(**login_kwargs)

此时可以获取一个 client。通过这个 client,可以对 mongodb 进行进一步访问。mongodb 默认没有密码:一方面对初学者非常友好;另外一方面也埋下了安全隐患,因为大家都会忘记设密码。

在进一步使用之前,需对 mongodb 进行一些说明:

  • 一个 mongodb 服务中,可以有多个 database
  • 每个 database 下面,又有多个 collection
  • 每个 collection 中存储着许多笔数据,每一笔数据用 key-value 的形式存储,类似 python 的 dict

如果一个 database 中没有 collection,这个 database 也不存在;如果一个 collection 中没有数据,这个 collection 也不存在。当访问 database 或者 collection 时候,如果不存在,则会被自动创建。在 pymongo 中,访问方式如下:

database = client['database_name']
collection = database['collection_name']
# collection.insert_one()

2.2 mongodb 各种角色

mongodb 有完善权限管理,不同角色对应不同权限。如果对已经有的角色权限不满意,还可以自己创建角色。mongodb 的权限有以下几种:

  • read
  • readWrite

也有预先创建好的角色,大概是这几种:

  • userAdmin 某一个 database 的用户管理员(针对数据库的用户,不能修改其它数据)
  • userAdminAnyDatabase 可以管理任意数据库
  • dbAdmin 某一个 database 的 crud 管理,不能管理用户
  • dbAdminAnyDatabase 所有 database 的 crud 管理
  • root 超级用户,拥有一切权限

mongodb 权限管理基于数据库(database),在配置角色时候,需要指定数据库。对于用户的管理和数据库的管理是分开的。实际上,对于用户的管理,操作的是 mongodb 的内置 database(名字叫做 admin)。

admindb = client.admin
admindb.command(
        "createUser",
        "dbadmin",
        pwd="dbadmin0",
        roles=[{"role": "dbAdminAnyDatabase", "db": "admin"}],
    )

创建好用户之后,需要重新运行服务器端的 mongodb,并且新增上相关命令:

mongod --auth

3. mongodb 备份与恢复

为了数据安全,需要定期备份数据。mongodb 也支持整个数据库备份与恢复。既可以在服务器端,也可以在客户端操作。这里介绍服务器端的备份恢复操作。

3.1 服务器端备份

使用 mongodump 进行备份,由于 mongodb 用 docker 运行,需要进入容器中:

docker exec ${container_name} mongodump ${dump_dir}

通常备份的结果在容器内部,备份完成后需要从容器内部复制出来:

docker cp ${container_name}:${dump_dir} ${host_local_path}

这样的备份会将所有的 database 和 collection 备份,可以新增 --database--collection 的方式指定 database 或者 collection。

3.2 服务器端恢复

现将备份好的文件夹复制到容器内部:

docker cp ${host_local_path} ${container_name}:${dump_dir}

在容器内部运行 mongorestore

docker exec ${container_name} mongorestore ${dump_dir}

4. 小结

本文介绍了 mongodb 的使用方式,用 docker 运行客户端,用 pymongo 进行连接和管理 mongodb,此外还介绍了在服务器端 mongodb 的备份与恢复。