返回文章列表

MongoDB 數據管理與 Cassandra 基礎操作實務

本文探討兩種主流 NoSQL 資料庫的實務操作。首先,詳細解說 MongoDB 的文檔刪除機制與利用 Docker 容器生命週期驗證數據持久性的方法,確保資料在服務中斷後依然完整。接著,介紹 Apache Cassandra 的基礎架構,從使用 Docker 快速部署開始,深入講解其核心概念 Keyspace

資料庫管理 容器化技術

在數據密集型應用中,NoSQL 資料庫因其高擴展性與靈活模型扮演關鍵角色。本文聚焦於兩種 NoSQL 典範:文件導向的 MongoDB 與寬列儲存的 Apache Cassandra。文章不僅闡述各自的數據操作語法,更關鍵的是將資料庫管理置於現代化的 DevOps 流程中。透過 Docker 容器技術,我們將探討如何標準化部署、管理服務生命週期,並驗證數據持久性。此方法論簡化了開發與測試流程,為構建高可用後端服務奠定基礎。從 MongoDB 的持久性驗證到 Cassandra 的 Keyspace 與 Table 管理,本文旨在提供一個從理論到實踐的操作藍圖,協助技術人員掌握在容器化環境下駕馭這兩大資料庫的核心技能。

MongoDB 文檔管理:刪除、容器生命週期與數據持久性驗證

本節將深入探討 MongoDB 中文檔的刪除操作,並藉由 Docker 容器的生命週期管理,來驗證數據持久性的實際效果。

刪除文檔

MongoDB 提供了 remove() 方法來刪除集合中的文檔。此方法可以根據指定的查詢條件來刪除一個或多個文檔。

  1. 刪除單一文檔: 要刪除集合中的特定文檔,需要提供一個包含篩選條件的查詢文檔。

    db.catalog.remove({ _id: ObjectId("561ff033380a18f6587b0aa5") })
    

    此命令會查找 _id"561ff033380a18f6587b0aa5" 的文檔,並將其從 catalog 集合中刪除。WriteResult 會顯示 nRemoved: 1,表示成功刪除了一個文檔。

    • 驗證刪除: 在執行 remove() 操作前後分別運行 db.catalog.find(),可以清晰地看到文檔數量的變化。如果之前有兩個文檔,刪除一個後將只剩一個。
  2. 刪除所有文檔: 要清空集合中的所有文檔,可以向 remove() 方法傳入一個空的查詢文檔 {}

    db.catalog.remove({})
    

    此命令會刪除 catalog 集合中的所有文檔。

    • 重要提示: 必須提供一個空的查詢文檔 {}。如果省略查詢文檔,MongoDB 會報錯,提示需要提供查詢條件,因為直接調用 remove() 而不帶任何參數是不允許的,這旨在防止意外刪除整個集合的數據。

停止與重啟 MongoDB 容器

使用 Docker 管理 MongoDB 實例時,我們可以通過 Docker 命令來控制容器的生命週期。這對於模擬服務中斷和恢復,以及驗證數據持久性至關重要。

  1. 停止容器: 使用 docker stop 命令來停止正在運行的 MongoDB 容器。

    sudo docker stop mongodb
    

    (請注意,原文示例中使用的是 mongo 作為容器名稱,這裡根據之前的設置使用 mongodb。)

  2. 查看運行中的容器: 執行 docker ps 命令,您會發現 mongodb 容器不再列於運行中的列表中。

  3. 啟動容器: 使用 docker start 命令來重新啟動已停止的容器。

    sudo docker start mongodb
    
  4. 再次確認運行狀態: 再次執行 docker ps,您將看到 mongodb 容器已重新啟動並正在運行。

  5. 進入容器與啟動 Shell

    • 啟動交互式終端: 使用 docker exec -it <container_id> bash 命令進入容器。這裡可以使用容器的 ID(例如 68fe88ca79fe)或名稱(mongodb)。
      sudo docker exec -it mongodb bash
      
    • 啟動 Mongo Shell: 在容器的 Shell 中,執行 mongo 命令來啟動 MongoDB 的交互式 Shell。
      mongo
      

數據持久性驗證

通過停止和重啟 Docker 容器,我們可以驗證 MongoDB 的數據持久性。由於我們在啟動容器時使用了 -v /data:/data 進行了數據卷掛載,即使容器被停止、刪除或重新創建,存儲在主機 /data 目錄下的數據也會被保留。

  1. 連接到恢復的數據庫: 在容器重啟並啟動 Mongo Shell 後,連接到 MongoDB 實例。

    mongo localhost:27017
    

    或連接到特定的數據庫:

    mongo localhost:27017/mongodb
    
  2. 驗證數據: 執行 show collectionsdb.catalog.find() 等命令,您應該能夠看到在容器停止前插入和更新的文檔依然存在。這證明了數據已經成功地從主機的數據卷中恢復。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

object "使用者" as User
object "Docker CLI" as DockerCLI
object "Docker Daemon" as DockerDaemon
object "Host Machine" as HostMachine
object "MongoDB Container (mongodb)" as MongoContainer
object "MongoDB Server" as MongoServer
object "Mongo Shell (CLI)" as MongoShell
object "Catalog Collection" as CatalogCollection

partition "文檔刪除操作" {
  User --> MongoShell : 執行 db.catalog.remove({ _id: ObjectId("...") })
  MongoShell --> CatalogCollection : 請求刪除特定文檔
  CatalogCollection --> MongoDB : 查找並移除文檔
  MongoServer --> User : 返回 WriteResult (nRemoved: 1)
  User --> MongoShell : 執行 db.catalog.find() (刪除前)
  MongoServer --> User : 列出剩餘文檔
  User --> MongoShell : 執行 db.catalog.remove({})
  MongoShell --> CatalogCollection : 請求刪除所有文檔
  CatalogCollection --> MongoDB : 移除集合內所有文檔
  MongoServer --> User : 返回 WriteResult (nRemoved: X)
  User --> MongoShell : 執行 db.catalog.find() (刪除後)
  MongoServer --> User : 集合為空
}

partition "Docker 容器生命週期與數據持久性" {
  User --> DockerCLI : 執行 sudo docker stop mongodb
  DockerCLI --> DockerDaemon : 請求停止容器
  DockerDaemon --> MongoContainer : 停止運行
  User --> DockerCLI : 執行 sudo docker ps
  DockerDaemon --> User : 顯示 mongodb 未運行
  User --> DockerCLI : 執行 sudo docker start mongodb
  DockerCLI --> DockerDaemon : 請求啟動容器
  DockerDaemon --> MongoContainer : 恢復運行 (掛載數據卷)
  User --> DockerCLI : 執行 sudo docker exec -it mongodb bash
  DockerCLI --> MongoContainer : 進入容器 Shell
  MongoContainer --> User : 提供容器 Shell 提示符
  User --> MongoShell : 執行 mongo 命令
  MongoShell --> MongoServer : 連接至 MongoDB 伺服器
  User --> MongoShell : 執行 db.catalog.find()
  MongoShell --> CatalogCollection : 查詢文檔
  MongoServer --> User : 顯示之前插入的文檔 (數據已恢復)
}

@enduml

看圖說話:

此圖示詳細闡述了 MongoDB 的文檔刪除操作以及通過 Docker 管理容器生命週期來驗證數據持久性的過程。在文檔刪除部分,圖示展示了如何通過 db.catalog.remove() 方法刪除單一文檔(通過指定 _id)和所有文檔(通過傳入空對象 {})。刪除操作前後的 db.catalog.find() 結果對比,清晰地展示了數據的移除。隨後,圖示聚焦於 Docker 容器的管理:使用者通過 docker stop 命令停止了 MongoDB 容器,docker ps 確認容器已停止運行。接著,docker start 命令重新啟動了容器,並再次使用 docker ps 驗證其運行狀態。最關鍵的是,在容器重啟後,使用者進入容器並啟動 Mongo Shell,然後執行 db.catalog.find(),結果顯示之前插入的文檔依然存在。這直接證明了由於數據卷掛載(-v /data:/data),MongoDB 的數據得到了持久化,即使容器被停止和重啟,數據也不會丟失。

####### 退出 Mongo Shell

完成所有操作後,可以通過以下命令退出 MongoDB 的交互式 Shell:

exit

或者在容器的 Bash Shell 中,也可以使用 exit 命令退出。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

object "使用者" as User
object "Mongo Shell (CLI)" as MongoShell
object "MongoDB Server" as MongoServer
object "Database (mongodb)" as MongoDB
object "Collection (catalog)" as CatalogCollection
object "Docker Container" as DockerContainer

partition "MongoDB 學習總結" {
  User --> DockerContainer : 啟動與管理 MongoDB 實例
  DockerContainer --> MongoDB : 提供數據存儲與處理
  MongoDB --> CatalogCollection : 存儲文檔數據
  CatalogCollection --> MongoDB : 執行 CRUD 操作
  MongoDB --> MongoShell : 響應 Shell 命令
  User --> MongoShell : 執行數據庫操作 (創建, 查詢, 更新, 刪除)
  MongoShell --> User : 返回操作結果與數據
  User --> MongoShell : 使用 mongodump/mongorestore 進行備份與恢復
  User --> DockerContainer : 停止與重啟容器,驗證數據持久性
  User --> MongoShell : 執行 exit 命令
  MongoShell --> User : 結束會話
}

partition "章節預覽" {
  object "下一章節" as NextChapter
  NextChapter : Apache Cassandra
  NextChapter : NoSQL 數據庫
  NextChapter : Keyspace, Column Family
  NextChapter : CQL (Cassandra Query Language)
  NextChapter : cqlsh 實用工具
  NextChapter : Docker 部署
}

@enduml

看圖說話:

此圖示總結了本章關於 MongoDB 的學習內容,並預告了下一章的主題。圖的左側部分展示了使用者如何通過 Mongo Shell 與 MongoDB 互動,進行數據庫、集合和文檔的各種操作(創建、讀取、更新、刪除),以及如何利用 Docker 管理容器並驗證數據的持久性。這涵蓋了從基礎到進階的 MongoDB 實踐。圖的右側則預告了下一章將要介紹的 Apache Cassandra,強調了它作為一種寬列 NoSQL 數據庫的特點,包括其核心概念如 Keyspace、Column Family,以及用於操作的 CQL 語言和 cqlsh 工具,並指出將會通過 Docker 進行部署。整體而言,圖示清晰地勾勒出本章的學習成果和未來探索的方向。

下一章節預告:Apache Cassandra 數據庫

在下一章中,我們將把目光轉向另一種重要的 NoSQL 數據庫:Apache Cassandra。Cassandra 是一種開源的、分佈式的、寬列存儲數據庫,以其高可用性、線性可擴展性和對海量數據的處理能力而聞名。

  • 核心概念:我們將學習 Cassandra 的核心架構,包括 Keyspace(類似於關聯式數據庫中的 Schema)和 Column Family(也稱為 Table,是數據的基本存儲單元)。
  • 數據模型:理解 Cassandra 的靈活模式(Schema-free 或 Dynamic Schema)數據模型,其中行可以擁有不同的列。
  • 操作語言:學習 Cassandra Query Language (CQL),這是一種用於執行數據增、刪、改、查(CRUD)操作的查詢語言。
  • 實踐部署:如同本章使用 Docker 部署 MongoDB 一樣,下一章也將介紹如何使用官方 Docker 鏡像來啟動和運行 Apache Cassandra,並通過 cqlsh 工具進行交互式操作。

我們將從設置環境、啟動 Cassandra 服務、連接到 CQL Shell,再到創建 Keyspace 和altering Keyspace 等基本操作開始,逐步深入了解 Cassandra 的強大功能。

Apache Cassandra 基礎:Keyspace、Table 操作與 Docker 部署

本章將引導您深入了解 Apache Cassandra 的基本操作,包括如何管理 KeyspaceTable,以及如何利用 Docker 快速部署和運行 Cassandra 實例。

環境準備與 Docker 部署

在開始之前,請確保您的環境已安裝以下必要軟體:

  • Docker:建議使用版本 1.8 或更新版本。
  • Apache Cassandra Docker 鏡像:我們將使用官方提供的 Docker 鏡像。

通常,我們會通過 SSH 連接到一個雲端伺服器(例如 Amazon EC2 實例)來進行這些操作,如同之前章節的設置一樣。

  1. 啟動 Apache Cassandra 容器: 使用 Docker 命令來啟動一個 Cassandra 實例。通常,這會涉及指定端口映射和數據卷掛載,以確保數據的持久性。

    # 範例命令,實際命令可能因版本和需求而異
    docker run --name cassandra -d -p 9042:9042 -v cassandra_data:/var/lib/cassandra cassandra:latest
    
    • --name cassandra:為容器指定一個名稱。
    • -d:以分離模式(後台運行)啟動容器。
    • -p 9042:9042:將主機的 9042 端口映射到容器的 9042 端口,這是 Cassandra 的默認 CQL 通信端口。
    • -v cassandra_data:/var/lib/cassandra:創建或使用一個名為 cassandra_data 的 Docker 數據卷,並將其掛載到容器內 Cassandra 的數據存儲目錄,以實現數據持久化。
    • cassandra:latest:指定使用的 Docker 鏡像及其標籤。
  2. 連接到 CQL Shell (cqlsh): 一旦 Cassandra 容器運行起來,我們就可以使用 cqlsh 工具來連接到它並執行 CQL 命令。

    • 在主機上運行 cqlsh: 如果 Cassandra 運行在本地 Docker 容器中,並且端口已映射,可以直接運行:
      cqlsh localhost 9042
      
    • 在容器內部運行 cqlsh: 或者,您可以進入 Cassandra 容器的 Shell,然後運行 cqlsh
      docker exec -it cassandra cqlsh
      

Keyspace 操作

在 Cassandra 中,Keyspace 是數據的頂層容器,類似於關係型數據庫中的 Schema 或 Database。它定義了數據的副本策略和一致性級別。

  1. 創建 Keyspace: 使用 CREATE KEYSPACE 語句來創建一個新的 Keyspace。

    CREATE KEYSPACE mykeyspace WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};
    
    • mykeyspace:您為 Keyspace 指定的名稱。
    • replication = {'class': 'SimpleStrategy', 'replication_factor': 1}:這是副本策略的定義。
      • SimpleStrategy:適用於單數據中心環境,只指定副本數量。
      • NetworkTopologyStrategy:適用於多數據中心環境,可以為每個數據中心指定副本數量。
      • replication_factor: 指定數據的副本數量。在生產環境中,通常設置為 3 或更高以確保高可用性。
  2. 使用 Keyspace: 創建 Keyspace 後,需要使用 USE 命令將其設置為當前工作的 Keyspace,之後的所有操作都將在此 Keyspace 下進行。

    USE mykeyspace;
    
  3. 修改 Keyspace: 可以使用 ALTER KEYSPACE 命令來修改現有 Keyspace 的屬性,例如副本策略。

    ALTER KEYSPACE mykeyspace WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 2};
    
  4. 刪除 Keyspace: 如果不再需要一個 Keyspace,可以使用 DROP KEYSPACE 命令將其及其包含的所有表和數據刪除。

    DROP KEYSPACE mykeyspace;
    

Table 操作

Table(或稱 Column Family)是 Cassandra 中存儲數據的基本單元,類似於關係型數據庫中的 Table。

  1. 創建 Table: 使用 CREATE TABLE 語句來定義一個新的 Table。Cassandra 的 Schema 比較靈活,但 Table 的定義仍然是必需的。

    CREATE TABLE users (
        user_id UUID PRIMARY KEY,
        first_name text,
        last_name text,
        email text,
        registration_date timestamp
    );
    
    • users:Table 的名稱。
    • user_id UUID PRIMARY KEY:定義了 user_id 作為主鍵,其類型為 UUID。在 Cassandra 中,主鍵是唯一標識一行記錄的關鍵。主鍵可以包含分區鍵(Partition Key)和聚簇鍵(Clustering Key)。
    • first_name text, last_name text, email text, registration_date timestamp:定義了 Table 的其他列及其數據類型。Cassandra 支持多種數據類型,如 text, int, uuid, timestamp, boolean, list, set, map 等。
  2. 添加 Table Data: 使用 INSERT INTO 語句向 Table 中添加數據。

    INSERT INTO users (user_id, first_name, last_name, email, registration_date)
    VALUES (uuid(), 'John', 'Doe', '[email protected]', toTimestamp(now()));
    
    • uuid():Cassandra 內置函數,用於生成一個新的 UUID。
    • now():Cassandra 內置函數,用於獲取當前時間戳。
    • toTimestamp():將其他類型(如 timeuuid)轉換為 timestamp 類型。
  3. 查詢 Table Data: 使用 SELECT 語句來查詢 Table 中的數據。

    • 查詢所有列
      SELECT * FROM users;
      
    • 查詢特定列
      SELECT first_name, email FROM users;
      
    • 帶條件查詢: Cassandra 的查詢能力在一定程度上受限於其分佈式架構。通常,查詢必須基於主鍵的一部分(特別是分區鍵)。
      SELECT * FROM users WHERE user_id = 123e4567-e89b-12d3-a456-426614174000;
      
  4. 更新 Table Data: Cassandra 中沒有顯式的 UPDATE 語句。更新操作實際上是插入一個具有相同主鍵的新記錄,新記錄中的字段值會覆蓋舊記錄中同名字段的值。

    INSERT INTO users (user_id, first_name, last_name)
    VALUES (123e4567-e89b-12d3-a456-426614174000, 'Jane', 'Smith');
    

    如果 user_id 相同,則 first_namelast_name 會被更新。

  5. 刪除 Table Data: 使用 DELETE 語句來刪除 Table 中的數據。

    • 刪除特定列
      DELETE email FROM users WHERE user_id = 123e4567-e89b-12d3-a456-426614174000;
      
    • 刪除整行記錄
      DELETE FROM users WHERE user_id = 123e4567-e89b-12d3-a456-426614174000;
      
  6. 截斷 TableTRUNCATE 命令會刪除 Table 中的所有數據,但保留 Table 的結構。

    TRUNCATE TABLE users;
    
  7. 刪除 Table: 如果不再需要一個 Table,可以使用 DROP TABLE 命令將其及其所有數據刪除。

    DROP TABLE users;
    

退出 CQL Shell 與停止 Cassandra

  • 退出 cqlsh: 在 cqlsh 交互式 Shell 中,輸入 exit 命令即可退出。

  • 停止 Cassandra 服務: 如果 Cassandra 是通過 Docker 運行的,則使用 docker stop <container_name_or_id> 命令來停止容器。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

object "使用者" as User
object "Docker CLI" as DockerCLI
object "Docker Daemon" as DockerDaemon
object "Host Machine" as HostMachine
object "Cassandra Container" as CassandraContainer
object "Cassandra Server" as CassandraServer
object "CQL Shell (cqlsh)" as CQLShell

partition "環境準備與 Docker 部署" {
  User --> DockerCLI : 執行 docker run 命令
  DockerCLI --> DockerDaemon : 請求創建並運行容器
  DockerDaemon --> CassandraContainer : 啟動 Cassandra 容器 (掛載數據卷)
  User --> DockerCLI : 執行 docker exec -it cassandra cqlsh
  DockerCLI --> CassandraContainer : 進入容器 Shell
  CassandraContainer --> CQLShell : 啟動 cqlsh
  User --> CQLShell : 執行 CQL 命令
}

partition "Keyspace 操作" {
  CQLShell --> CassandraServer : 執行 CREATE KEYSPACE mykeyspace WITH replication = ...
  CassandraServer --> User : 返回操作結果
  CQLShell --> CassandraServer : 執行 USE mykeyspace
  CassandraServer --> User : 確認當前 Keyspace
  CQLShell --> CassandraServer : 執行 ALTER KEYSPACE mykeyspace WITH replication = ...
  CQLShell --> CassandraServer : 執行 DROP KEYSPACE mykeyspace
}

partition "Table 操作" {
  CQLShell --> CassandraServer : 執行 CREATE TABLE users (...)
  CassandraServer --> User : 返回 Table 創建結果
  CQLShell --> CassandraServer : 執行 INSERT INTO users (...) VALUES (...)
  CassandraServer --> User : 返回插入結果
  CQLShell --> CassandraServer : 執行 SELECT * FROM users
  CassandraServer --> User : 返回查詢結果
  CQLShell --> CassandraServer : 執行 DELETE FROM users WHERE ...
  CassandraServer --> User : 返回刪除結果
  CQLShell --> CassandraServer : 執行 TRUNCATE TABLE users
  CQLShell --> CassandraServer : 執行 DROP TABLE users
}

partition "退出與停止" {
  CQLShell --> User : 輸入 exit 命令
  User --> DockerCLI : 執行 docker stop cassandra
  DockerCLI --> DockerDaemon : 請求停止容器
}

@enduml

看圖說話:

此圖示詳細闡述了 Apache Cassandra 的基礎操作流程,從環境準備到數據管理,再到服務的停止。首先,使用者通過 Docker CLI 啟動 Cassandra 容器,並進入容器內的 cqlsh 環境。接著,圖示展示了 Keyspace 的完整生命週期管理,包括創建、使用、修改和刪除。隨後,重點描繪了 Table 的操作,涵蓋了創建 Table、插入數據、查詢數據(包括帶條件查詢)、更新數據(通過插入新記錄)、刪除數據(單行或單列)以及截斷和刪除整個 Table。最後,圖示展示了如何退出 cqlsh Shell 以及如何通過 Docker 命令停止 Cassandra 容器。整個流程清晰地呈現了 Cassandra 的基本數據模型和操作方式,為後續更深入的學習奠定了基礎。

從單一技術的深度實踐,過渡到多元工具的廣度探索,其核心不僅是技能的擴展,更是技術領導者思維框架的突破。本文從 MongoDB 的數據持久性驗證,到 Cassandra 的基礎架構操作,看似是兩種工具的學習路徑,實則揭示了從「單點精通」邁向「系統性選型」的關鍵躍升。技術專家轉換工具的最大瓶頸,並非語法學習,而是未能擺脫既有數據模型的思維慣性。真正的突破在於能依據業務場景、擴展性與可用性目標,權衡不同架構優劣,將技術能力轉化為架構決策價值。

未來,「多語言持久化」(Polyglot Persistence)將成為主流。成功的技術領導者不再是單一工具專家,而是能駕馭多元數據方案、構建混合式平台的系統架構師。這種跨典範的學習與實踐驗證,是技術領導者突破個人能力天花板、驅動組織技術創新的必經之路,值得投入策略性時間進行深度佈局。