亚马逊AWS官方博客

向风而行 随需而动 云原生文档数据库 DocumentDB Elastic Cluster 实现副本集到分片架构的无缝扩展

前言

Amazon DocumentDB(与 MongoDB 兼容)是一种可扩展、高度持久和完全托管的云原生文档数据库服务,用于操作任务关键型 JSON 工作负载。它是 AWS 快速增长的服务之一,包括英国广播公司、道琼斯和三星在内的客户都依赖 Amazon DocumentDB 来大规模运行其 JSON 工作负载。

为了更好地实现客户对文档数据库的横向扩展需求, 我们在 2022 年 12 月正式发布 Amazon DocumentDB Elastic Clusters , Elastic Clusters 让您随着业务需求扩展,能够随需而动,弹性地扩展文档数据库,处理几乎任意数量的写入和读取,以及可储存 PB 级数据。

Elastic Clusters 简介和特点

分片 — 一种流行的数据库概念,也称为分区,将大型数据集拆分为多个节点上的较小数据集,让客户能够在垂直扩展限制之外横向扩展数据库。Elastic Clusters 利用分片技术在 Amazon DocumentDB 的云原生分布式存储系统中对数据进行分区。

Elastic Clusters — Elastic Clusters 是 Amazon DocumentDB 完全托管的云原生文档数据库分片集群,可以将客户工作负载的吞吐量扩展到每秒数百万次写入/读取,将数据存储扩展到 PB 级。Elastic Clusters 由一个或多个分片组成,最多可达 32 个分片,每个分片都有自己的计算和存储容量。缺省就是最高可用性,可实现跨三个可用区(AZ)的高可用性,每份数据以六个数据副本将跨三个可用区复制。

随需而动 极限扩展  Elastic Clusters 让您随着业务需求扩展,能够随需而动,弹性地扩展文档数据库,扩展到每秒数百万次写入/读取,将数据存储扩展到 PB 级。

弹性伸缩 扩展无感知 — 借助 Elastic Clusters,可将数据库扩展到每秒数百万次操作,扩展过程中几乎不会出现停机或影响性能。

跨三个可用区(AZ)高可用 缺省就是跨三个可用区(AZ)的高可用性,每份数据以六个数据副本将跨三个可用区复制,最多可以容忍 AZ+1 故障。

缺省实施安全最佳实践 – 可实现透明数据库加密存储,加密数据传输 SSL/TLS, 以及 VPC 内安全访问,满足多项行业认证安全合规。

无缝集成 — Elastic Clusters 与其它 AWS 服务集成,就像之前的 Amazon DocumentDB 副本集架构 DocumentDB Instance Cluster 一样。可以无缝与 Amazon CloudWatch 集成,监控 Elastic Clusters 的运行状况和性能,通过 AWS Identity and Access Management (IAM) 用户和角色为集群等资源设置身份验证和授权,并使用 Amazon Virtual Private Cloud (Amazon VPC) 实现仅限 VPC 的安全连接。可以使用 AWS Glue 从其他 AWS 服务导入和导出数据,例如 Amazon Simple Storage Service (Amazon S3)Amazon Redshift 和 Amazon OpenSearch Service

本博客将以示例随着业务扩展,数据量增长,原有交易应用所使用 DocumentDB Instance Cluster(副本集架构)不能更好地满足系统扩展,希望能将 DocumentDB Instance Cluster(副本集架构)迁移到 DocumentDB Elastic Cluster(分片架构)获取更高的写能力和数据存储扩展, 通过介绍如何实现整个迁移过程, 来向您展示云原生文档数据库 DocumentDB Elastic Cluster 如何向风而行,随需而动,实现副本集到分片架构的无缝扩展。

创建目标 DocumentDB Elastic Cluster

  1. 创建区域选择 us-east-1, 访问 DocumentDB Console: https://us-east-1.console.aws.amazon.com/docdb/home?region=us-east-1#clusters
  2. 创建 DocumentDB Elastic Cluster
    Cluster_name: Elastic_cluster_blog
    Cluster Configuration: 2个 Shard, 每个 Shard 2 VCPU

选择集群创建的 VPC(default VPC)、安全组(default)以及主用户(masteruser), 其它选项选择缺省,点击创建:

创建源端 DocumentDB Instance Cluster

  1. 创建区域选择 us-east-1, 访问 DocumentDB Console: https://us-east-1.console.aws.amazon.com/docdb/home?region=us-east-1#clusters
  2. 创建 DocumentDB Instance Cluster
    Cluster_name: Instance_cluster_blog
    English Version: 4.0.0
    Instance Class: db.t3.medium
    Number of instances:1

输入主用户名:masteruser 和密码, 其它选项选择缺省,点击创建。

迁移源端 DocumentDB Instance Cluster 数据准备

  1. 准备测试 EC2 堡垒机:
    Name: docdb-instance-elastic
    OS Images: Amazon Linux 2
    Instance type: t2.micro
    点击创建
  1. 修改 EC2 堡垒机,修改 security group

    增加 security group: default

  1. 连接到 EC2 堡垒机,安装 Mongoshell
    echo -e "[mongodb-org-4.0] \nname=MongoDB Repository\nbaseurl=https://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/4.0/x86_64/\ngpgcheck=1 \nenabled=1 \ngpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc" | sudo tee /etc/yum.repos.d/mongodb-org-4.0.repo

    完成之后,使用以下命令安装 Mongoshell

    sudo yum install -y mongodb-org-shell
  1. 连接到 EC2 堡垒机,安装数据导入工具 Mongoimport
    sudo yum install mongodb-org-tools
  1. 导入交易 demo 数据 – transactions.json
    sudo yum install git
    
    git clone https://github.com/bingbingliu18/docdb-elastic-cluster-blog
    
    cd docdb-elastic-cluster-blog
    
    ls transactions.json
    
  1. 将交易 demo 数据(transactions.json)导入到 DocumentDB Instance Cluster
    a)进入到 transactions.json 下载目录:

    cd docdb-elastic-cluster-blog

    b)下载链接到 DocumentDB Instance Cluster 证书:

    wget https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem

    c)将交易数据(json)导入到 DocumentDB Instance Cluster(替换成您的 clusterEndpoint 和 username/password)

           mongoimport --ssl --host=<clusterEndpoint> --collection=transactions --db=testdb --file=transactions.json --numInsertionWorkers 4 --username=<username> --password=<password> --sslCAFile rds-combined-ca-bundle.pem
  1. 连接到 DocumentDB Instance Cluster 查看已经导入的交易数据(替换成您的 clusterEndpoint 和 username/password):
    mongo --ssl --host instance-cluster-blog.ckutjdcz3cie.us-east-1.docdb.amazonaws.com:27017 --sslCAFile rds-combined-ca-bundle.pem --username masteruser --password <insertYourPassword>
    
    use testdb
    show collections
    db.transactions.find().count()
    共有 1746 条记录
    db.transactions.findOne()
    

    Transactions Collection 的主要字段示例:

          "_id" : ObjectId("5ca4bbc1a2dd94ee58161cb4"),
    	"accountid" : 278603, (客户id信息)
    	"transaction_count" : 83,
    	"bucket_start_date" : ISODate("1975-06-02T00:00:00Z"),
    	"bucket_end_date" : ISODate("2017-01-04T00:00:00Z"),
    	"transactions" : [
    		{
    			"date" : ISODate("2016-09-13T00:00:00Z"),
    			"amount" : 3425,
    			"transaction_code" : "buy",
    			"symbol" : "goog",
    			"price" : "758.15476355428472743369638919830322265625",
    			"total" : "2596680.065173425191460410133"
    		} (客户具体交易信息)
             …

迁移副本集数据到分片架构

随着业务扩展,数据量增长,原有交易应用所使用 DocumentDB Instance Cluster(副本集架构)不能更好地满足系统扩展,希望能将 DocumentDB Instance Cluster(副本集架构)迁移到 DocumentDB Elastic Cluster(分片架构)获取更高的写能力和数据存储扩展。

交易数据为了能实现更好的扩展,需要将交易 Collection 转换成交易分片Collection,目前 DocumentDB Elastic Cluster 支持哈希分片。

在建立分片 Collection时,选择合适的分片键需基于以下原则:

  • 选择高基数字段(大量唯一值)– 很好的例子是 employeeId, customerId, sessionId, orderId。
  • 分片键频率和使用模式 – 选择与查询类型一致的分片键。
  • 使用均匀分布的哈希键将数据分布到集群中的所有分片(避免使用热键)。

基于以上原则,交易 Transactions collection 中高基数字段和在应用查询频繁使用的字段是客户 ID(accountid), 所以后续会采用 accountid 字段对 Transactions collection 进行分片。

关于如何迁移副本集数据到分片架构, 我们会建议采用 AWS Data Migration Service 来实现 DocumentDB 副本集架构数据到 DocumentDB Elastic Cluster 的数据迁移。

AWS Database Migration Service(AWS DMS)是一项云服务,允许迁移关系数据库、数据仓库、NoSQL 数据库和其他类型的数据存储, 支持以 DocumentDB 为源和目标的数据迁移。

迁移架构图:

具体迁移步骤如下:

1. 打开源端 DocumentDB Instance Cluster 变更流捕获, 为源端 CDC 做准备:

连接到源端 DocumentDB Instance Cluster

wget https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem

mongo --ssl --host instance-cluster-blog.cluster-ckutjdcz3cie.us-east-1.docdb.amazonaws.com:27017 --sslCAFile rds-combined-ca-bundle.pem --username masteruser --password <insertYourPassword>

在集群级别启用 DocumentDB 变更流,集群上所有数据库上的数据变化都将被捕获至 DocumentDB Change Stream:

db.adminCommand({modifyChangeStreams: 1, database: "", collection: "", enable: true});

您应得到以下响应结果:

{ "ok" : 1 }

2. 创建 DMS Replication Instance

Name: dms-replication-elastic
Instance Class: dms.t3.medium

注意事项:Replication instance 在生产环境中会大量消耗 replication instance 的 CPU 和内存,如果资源不足会影响迁移速度,本博客是为了帮助您熟悉流程,采用了 t 系列资源,而实际迁移环境中, 请您不要使用 t 系列。

Engine version: 3.4.7
Multi AZ: Single-AZ
Public accessible: 不勾选
其它项:输入缺省值
点击创建

3. 创建 DMS Source Endpoint 为源端 DocumentDB Instance Cluster

Endpoint Type: Source Endpoint
Endpoint Name: Docdb-Elastic-Blog-source
Source Engine: Amazon DocumentDB (with MongoDB Compatibility)
Access to endpoint database: Provide access information manually
Server Name: your DocumentDB Instance Cluster Endpoint
Port: 27017
Secure Socket Layer(SSL) mode: verify-full
下载 SSL 证书到本地电脑: https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem
导入本地电脑证书并取名为 CA
User name: masteruser
Password: your password
Database name: testdb
其它项:输入缺省值
点击创建 Endpoint

测试刚创建的 DMS Source Endpoint:

4. 创建 DMS Target Endpoint 为端 DocumentDB Elastic Cluster

Endpoint Type: Target Endpoint
Endpoint Name: Docdb-Elastic-Blog-target
Source Engine: Amazon DocumentDB (with MongoDB Compatibility)
Access to endpoint database: Provide access information manually
Server Name: your DocumentDB Instance Cluster Endpoint
Port: 27017
Secure Socket Layer(SSL) mode: verify-full
下载 SSL 证书到本地电脑:https://www.amazontrust.com/repository/SFSRootCAG2.pem
导入本地电脑证书并取名为 CA-Elastic
User name: masteruser
Password: your password
Database name: testdb
其它项:输入缺省值
点击创建 Endpoint

测试刚创建的 DMS Target Endpoint:

5. 在目标端 Elastic Cluster 预先创建交易(Transactions)分片 Collection (基于客户 id 来做分片

登录到 EC2 堡垒机, 通过 MongoShell 连接到目标端 Elastic Cluster (替换 Password 和 Cluster Endpoint)

mongo mongodb://masteruser:<insertPassword>@Elastic-cluster-blog-028183925784.us-east-1.docdb-elastic.amazonaws.com:27017 -ssl

use testdb
sh.shardCollection("testdb.transactions" , { "accountid" : "hashed" })

创建成功:

{ "ok" : 1 }

6. 创建 DMS 迁移任务实现从 DocumentDB Instance Cluster DocumentDB Elastic Cluster 的交易数据迁移全量数据数据 + 增量数据

Task identifier: dms-elastic-task
Migration Type: Migrate Existing Data and replicate ongoing changes
Replication instance: dms-replication-elastic
Source database endpoint: docdb-elastic-blog-source
Target database endpoint: docdb-elastic-blog-target
Target Table Preparation Mode: Do Nothing(这里请注意 一定要选择 Do Nothing 在前面步骤 已经预先定义分片 Collection)
Schema: Enter a schema
Source Name: testdb
Source Table Name: transactions
其他输入项:保持缺省配置
点击创建

DMS 任务创建后会自动启动观测 DMS 任务执行(已经完成全量数据 1746 rows 同步):

登录到 EC2 堡垒机,通过 Mongoshell 连接到源端 DocumentDB Instance Cluster,插入一条记录:

rs0:PRIMARY> db.transactions.insert({"accountid" : 999199, "transaction_count" : 56, "bucket_start_date" : ISODate("2022-06-11T00:00:00Z"), "bucket_end_date" : ISODate("2022-11-06T00:00:00Z"), "transactions" : [ { "date" : ISODate("2022-10-06T00:00:00Z"), "amount" : 2561, "transaction_code" : "sell", "symbol" : "adbe", "price" : "38.236619210617988073863671161234378814697265625", "total" : "97923.98179839266745716486184" }]})
WriteResult({ "nInserted" : 1 })

再次观测 DMS 任务执行 (DMS CDC 任务已捕获到新插入记录):

7. 查询分片 Transactions Collection 迁移数据在各个分片上的数据分布:

创建 CloudWatch Dashboard
Dashboard Name: docdb-elastic-blog
Type: Metrics
Metrics 类别:AWS/DocDB-Elastic (CloudWatch 新增加 DocDB Elastic 类别)
选择 ClusterId,ClusterName,ShardId
输入过滤条件:elastic-cluster-blog DocumentsInserted
基于筛选出的指标创建 Dashboard Widget:

通过观测 DocumentDB Elastic Cluster 两个分片上的 DocumentsInserted 指标,可以看到在数据迁移的整个过程中,数据被通过 Hash 分片均匀分布在两个分片上:

8. 迁移到分片集群后最佳实践:

  • 在插入分片 Collection 数据时,必须具有分片键数据,否则会报错。示例如下:
mongos> db.transactions.insert({"transaction_count" : 56, "bucket_start_date" : ISODate("2022-06-11T00:00:00Z")})
"errmsg" : "Insert for sharded collection must have shardKey"
  • Shardkey 命名须满足正则表达式“regex ‘^[a-zA-Z][a-zA-Z0-9]” 以字母开头,由大小写字母和数字组成。
  • 非分片 Colletion 会部署在 Database 缺省的主分片上。
  • 在所有读取/更新/删除请求中使用分片键,以避免分散收集查询。
  • 执行读取/更新/删除操作时避免嵌套分片键。
  • 进行批处理操作时,请将 ordered 设置为 false,以便所有分片可以并行运行并改善延迟。

DocumentDB Elastic Cluster 的弹性扩展

上面章节已经向您展示,如何将副本集架构 DocumentDB Instance Cluster 上的交易数据使用 DMS 无缝迁移到具有两个分片的分片架构 DocumentDB Elastic Cluster。随着业务进一步扩展,需要有更高的写入吞吐和存储容量,当前的两分片架构已经不能满足业务支撑,需进一步扩展。此时我们可以采用 DocumentDB Elastic Cluster 在线增加分片,实现横向扩展,DocumentDB Elastic Cluster 最多可扩展至 32 分片,以下示例中,会将分片由原有两个在线弹性扩展至四个,修改 DocumentDB Elastic Cluster 集群, 修改 Shard Count 为 4:

DocumentDB Elastic Cluster 可以实现弹性伸缩、在线扩展,并且整个扩展可做到扩展无感知,整个扩展过程中几乎不会出现停机或影响性能。

总结

通过本博客介绍示例的随着业务扩展,数据量增长,原有交易应用所使用 DocumentDB Instance Cluster(副本集架构)不能更好地满足系统扩展,需要无缝地将 DocumentDB Instance Cluster(副本集架构)迁移到 DocumentDB Elastic Cluster(分片架构)获取更高的写能力和数据存储扩展,希望在此通过此博客,您已经深入了解了 Amazon DocumentDB Elastic Cluster 云原生文档数据库分片架构,洞悉 DocumentDB Elastic Cluster 托管的云原生文档数据库分片架构的高性能、高扩展、高安全和高可用特性,从而即刻构建您的云原生文档数据库分片集群 DocumentDB Elastic Cluster,来承载您的关键型 JSON 工作负载!

本篇作者

Bingbing Liu

AWS 数据库解决方案架构师,负责基于 AWS 的数据库解决方案的咨询与架构设计,同时致力于大数据方面的研究和推广。在加入 AWS 之前曾在 Oracle 工作多年,在数据库云规划、设计运维调优、DR 解决方案、大数据和数仓以及企业应用等方面有丰富的经验。