本文目標是快速搭建一套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}

總結

本文介紹了mongodb的使用方式,用 docker 執行用戶端,用pymongo進行連線和管理mongodb,此外還介紹了在伺服器端mongodb的備份與恢復。