本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
从 Couchbase 服务器迁移
简介
本指南介绍了从Couchbase Server迁移到亚马逊DocumentDB时需要考虑的关键点。它解释了迁移发现、规划、执行和验证阶段的注意事项。它还解释了如何执行离线和在线迁移。
与亚马逊 DocumentDB 的比较
| Couchbase 服务器 | Amazon DocumentDB | |
|---|---|---|
| 数据组织 | 在 7.0 及更高版本中,数据按存储桶、范围和集合进行组织。在早期版本中,数据按存储桶进行组织。 | 数据被组织到数据库和集合中。 |
| 兼容性 | 每项服务(例如数据、索引、搜索等)都有单独的 API。二次查找使用 SQL++(以前称为 N1QL);这是一种基于 ANSI-standard SQL 的查询语言,因此许多开发人员都熟悉它。 | Amazon DocumentDB 与 MongoDB API 兼容。 |
| 架构 | 存储器连接到每个集群实例。您不能独立于存储扩展计算。 | Amazon DocumentDB 专为云端而设计,旨在避开传统数据库架构的限制。在 Amazon DocumentDB 中,计算层和存储层是分开的,计算层可以独立于存储how-it-works.html进行扩展。 |
| 按需增加读取容量 | 可以通过添加实例来扩展集群。由于存储连接到运行服务的实例,因此向外扩展所需的时间取决于需要移动到新实例或重新平衡的数据量。 | 通过在集群中创建最多 15 个 Amazon DocumentDB 副本,您可以实现该集群的读取扩展。对存储层没有影响。 |
| 快速从节点故障中恢复 | 集群具有自动故障转移功能,但使集群恢复满负荷的时间取决于需要移动到新实例的数据量。 | Amazon DocumentDB 通常可以在 30 秒内对主集群进行故障转移,无论集群中的数据量是多少,都可在 8-10 分钟内将集群恢复到最大强度。 |
| 随着数据的增长扩展存储 | 对于自管理集群,存储和 iOS 不会自动扩展。 | 亚马逊 DocumentDB 存储空间和 iOS 可自动扩展。 |
| 在不影响性能的情况下备份数据 | 备份由备份服务执行,默认情况下未启用。由于存储和计算没有分开,因此可能会对性能产生影响。 | Amazon DocumentDB 备份默认处于启用状态,无法关闭。备份由存储层处理,因此对计算层的影响为零。Amazon DocumentDB 支持从集群快照恢复和恢复到某个时间点。 |
| 数据耐久性 | 一个集群中最多可以有 3 个数据副本副本,总共有 4 个副本。运行数据服务的每个实例都将有活动数据和 1、2 或 3 个副本副本。 | 无论有多少计算实例,Amazon DocumentDB 都会保留 6 个数据副本,写入法定人数为 4,并且保持不变。存储层保留了 4 个数据副本后,客户端会收到确认。 |
| 一致性 | 支持 K/V 操作的即时一致性。Couchbase SDK 会将 K/V 请求路由到包含数据活动副本的特定实例,因此,一旦确认更新,就可以保证客户端读取该更新。将更新复制到其他服务(索引、搜索、分析、事件)最终是一致的。 | Amazon DocumentDB 副本最终是一致的。如果需要立即进行一致性读取,则客户端可以从主实例读取。 |
| 复制 | Cross-Data 中心复制 (XDCR) 提供多:多拓扑中经过筛选passive/active的主动数据复制。 | Amazon DocumentDB 全球集群在 1:many(最多 10 个)拓扑中提供主动-被动复制。 |
Discovery
迁移到 Amazon DocumentDB 需要透彻了解现有的数据库工作负载。工作负载发现是分析 Couchbase 集群配置和操作特征(数据集、索引和工作负载)的过程,旨在帮助确保以最小的干扰实现无缝过渡。
集群配置
Couchbase 使用以服务为中心的架构,其中每种功能都对应一项服务。对您的 Couchbase 集群执行以下命令以确定正在使用哪些服务(请参阅获取节点
curl -v -u <administrator>:<password> \ http://<ip-address-or-hostname>:<port>/pools/nodes | \ jq '[.nodes[].services[]] | unique'
示例输出:
[ "backup", "cbas", "eventing", "fts", "index", "kv", "n1ql" ]
Couchbase 服务包括以下内容:
数据服务 (kv)
数据服务提供对内存和磁盘上数据的 read/write 访问。
Amazon DocumentDB 支持通过 MongoDB API 对 JSON 数据进行 K/V 操作。
查询服务 (n1ql)
该查询服务支持通过 SQL++ 查询 JSON 数据。
Amazon DocumentDB 支持通过 MongoDB API 查询 JSON 数据。
索引服务(索引)
索引服务创建和维护数据索引,从而加快查询速度。
亚马逊文档数据库支持默认主索引以及通过 MongoDB API 在 JSON 数据上创建二级索引。
搜索服务 (fts)
搜索服务支持为全文搜索创建索引。
Amazon DocumentDB 的原生全文搜索功能允许您使用 API 使用特殊用途的文本索引对大型文本数据集执行基本文本查询。MongoDB要获得模糊搜索、多语言搜索和交叉馆藏搜索等高级功能,请使用 Amazon DocumentDB Zero-ETL 与亚马逊服务的集成。 OpenSearch
分析服务 (cba)
分析服务支持近乎实时地分析 JSON 数据。
Amazon DocumentDB 支持通过 MongoDB API 对 JSON 数据进行临时查询。你还可以使用在亚马逊 EM R 上
事件服务(事件)
事件服务执行用户定义的业务逻辑以响应数据变化。
每当您的亚马逊文档数据库集群发生数据变化时,Amazon DocumentDB都会调用 AWS Lambda 函数,从而自动执行事件驱动的工作负载。
备份服务(备份)
备份服务计划完整和增量数据备份以及先前数据备份的合并。
Amazon DocumentDB 会持续将您的数据备份到 Amazon S3,保留期为 1—35 天,因此您可以快速恢复到备份保留期内的任何时间点。作为持续备份过程的一部分,Amazon DocumentDB 还会自动拍摄数据快照。您还可以使用管理亚马逊 DocumentDB 的备份和恢复。 AWS Backup
操作特性
使用适用于 Couchbase 的
数据集
该工具检索以下存储桶、范围和集合信息:
存储桶名称
存储桶类型
范围名称
馆藏名称
总大小(字节)
物品总数
项目大小(字节)
索引
该工具检索以下索引统计数据和所有存储桶的所有索引定义。请注意,由于 Amazon DocumentDB 会自动为每个集合创建主索引,因此不包括主索引。
存储桶名称
范围名称
馆藏名称
索引名
索引大小(字节)
工作负载
该工具检索 K/V 和 N1QL 查询指标。 K/V 指标值在存储桶级别收集,SQL++ 指标在集群级别收集。
工具命令行选项如下所示:
python3 discovery.py \ --username <source cluster username> \ --password <source cluster password> \ --data_node <data node IP address or DNS name> \ --admin_port <administration http REST port> \ --kv_zoom <get bucket statistics for specified interval> \ --tools_path <full path to Couchbase tools> \ --index_metrics <gather index definitions and SQL++ metrics> \ --indexer_port <indexer service http REST port> \ --n1ql_start <start time for sampling> \ --n1ql_step <sample interval over the sample period>
以下是一个示例命令:
python3 discovery.py \ --username username \ --password ******** \ --data_node "http://10.0.0.1" \ --admin_port 8091 \ --kv_zoom week \ --tools_path "/opt/couchbase/bin" \ --index_metrics true \ --indexer_port 9102 \ --n1ql_start -60000 \ --n1ql_step 1000
K/V 指标值将基于过去一周每 10 分钟的样本(请参阅 HTTP 方法和 URI
collection-stats.csv — 存储桶、范围和集合信息
bucket,bucket_type,scope_name,collection_name,total_size,total_items,document_size beer-sample,membase,_default,_default,2796956,7303,383 gamesim-sample,membase,_default,_default,114275,586,196 pillowfight,membase,_default,_default,1901907769,1000006,1902 travel-sample,membase,inventory,airport,547914,1968,279 travel-sample,membase,inventory,airline,117261,187,628 travel-sample,membase,inventory,route,13402503,24024,558 travel-sample,membase,inventory,landmark,3072746,4495,684 travel-sample,membase,inventory,hotel,4086989,917,4457 ...
index-stats.csv — 索引名称和大小
bucket,scope,collection,index-name,index-size beer-sample,_default,_default,beer_primary,468144 gamesim-sample,_default,_default,gamesim_primary,87081 travel-sample,inventory,airline,def_inventory_airline_primary,198290 travel-sample,inventory,airport,def_inventory_airport_airportname,513805 travel-sample,inventory,airport,def_inventory_airport_city,487289 travel-sample,inventory,airport,def_inventory_airport_faa,526343 travel-sample,inventory,airport,def_inventory_airport_primary,287475 travel-sample,inventory,hotel,def_inventory_hotel_city,497125 ...
kv-stats.csv — 获取、设置和删除所有存储桶的指标
bucket,gets,sets,deletes beer-sample,0,0,0 gamesim-sample,0,0,0 pillowfight,369,521,194 travel-sample,0,0,0
n1ql-stats.csv — SQL++ 选择、删除和插入集群的指标
selects,deletes,inserts 0,132,87
索引-<bucket-name>.txt — 存储桶中所有索引的索引定义。请注意,由于 Amazon DocumentDB 会自动为每个集合创建主索引,因此不包括主索引。
CREATE INDEX `def_airportname` ON `travel-sample`(`airportname`) CREATE INDEX `def_city` ON `travel-sample`(`city`) CREATE INDEX `def_faa` ON `travel-sample`(`faa`) CREATE INDEX `def_icao` ON `travel-sample`(`icao`) CREATE INDEX `def_inventory_airport_city` ON `travel-sample`.`inventory`.`airport`(`city`) CREATE INDEX `def_inventory_airport_faa` ON `travel-sample`.`inventory`.`airport`(`faa`) CREATE INDEX `def_inventory_hotel_city` ON `travel-sample`.`inventory`.`hotel`(`city`) CREATE INDEX `def_inventory_landmark_city` ON `travel-sample`.`inventory`.`landmark`(`city`) CREATE INDEX `def_sourceairport` ON `travel-sample`(`sourceairport`) ...
规划
在规划阶段,您将确定亚马逊文档数据库集群要求,并将Couchbase存储桶、范围和集合映射到亚马逊文档数据库和集合。
亚马逊 DocumentDB 集群要求
使用发现阶段收集的数据来调整您的 Amazon DocumentDB 集群的大小。有关调整 Amazon DocumentDB 集群大小的更多信息,请参阅实例大小。
将存储桶、范围和集合映射到数据库和集合
确定您的亚马逊 DocumentDB 集群中将存在的数据库和集合。根据您的 Couchbase 集群中数据的组织方式,考虑以下选项。这些不是唯一的选择,但它们提供了供您考虑的起点。
Couchbase 服务器 6.x 或更早版本
Couchbase 存储桶转化为亚马逊 DocumentDB 馆藏
将每个存储桶迁移到不同的 Amazon DocumentDB 集合。在这种情况下,Couchbase 文档id值将用作亚马逊 DocumentD _id B 的值。
Couchbase 服务器 7.0 或更高版本
Couchbase 集合到亚马逊 DocumentDB 集合
将每个集合迁移到不同的 Amazon DocumentDB 集合。在这种情况下,Couchbase 文档id值将用作亚马逊 DocumentD _id B 的值。
迁移
索引迁移
迁移到 Amazon DocumentDB 不仅涉及传输数据,还包括传输索引,以保持查询性能和优化数据库操作。本节概述了在确保兼容性和效率的同时将索引迁移到 Amazon DocumentDB 的详细分步流程。
使用 A mazon Q(在 AWS 管理控制台或 IDE 中可用)将 SQL++ CREATE INDEX 语句转换为 Amazon DocumentD createIndex() B 命令。
上传<bucket name>由 Couchbase 探索工具创建的索引-.txt 文件。
输入以下提示:
Convert the Couchbase CREATE INDEX statements to Amazon DocumentDB createIndex commands
亚马逊 Q 将生成等效的 Amazon DocumentDB createIndex() 命令。请注意,您可能需要根据将 Couchbase 存储桶、范围和集合映射到 Amazon DocumentDB 集合的方式更新集合名称。
例如:
indexes-beer-sample.txt
CREATE INDEX `beerType` ON `beer-sample`(`type`) CREATE INDEX `code` ON `beer-sample`(`code`) WHERE (`type` = "brewery")
亚马逊 Q 输出示例(摘录):
db.beerSample.createIndex( { "type": 1 }, { "name": "beerType", "background": true } ) db.beerSample.createIndex( { "code": 1 }, { "name": "code", "background": true, "partialFilterExpression": { "type": "brewery" } } )
有关 Amazon Q 无法转换的任何索引,请参阅管理 Amazon DocumentDB 索引以及索引和索引属性以了解更多信息。
重构代码以使用 MongoDB API
客户端使用 Couchbase SDK 连接到 Couchbase 服务器。亚马逊 DocumentDB 客户端使用 MongoDB 驱动程序连接到亚马逊 DocumentDB。MongoDB 驱动程序也支持 Couchbase 开发工具包支持的所有语言。有关适用于您的语言的驱动程序的更多信息,请参见
由于 Couchbase Server 和 Amazon DocumentDB 之间的 API 不同,因此您需要重构代码才能使用相应的 MongoDB API。您可以使用 Amazon Q 将 K/V API 调用和 SQL++ 查询转换为等效的 MongoDB API:
上传源代码文件。
输入以下提示:
Convert the Couchbase API code to Amazon DocumentDB API code
使用 Hello Couchbase
from pymongo import MongoClient # Connection parameters database_name = "travel-sample" # Connect to Amazon DocumentDB cluster client = MongoClient('<Amazon DocumentDB connection string>', tls=True, tlsCAFile='global-bundle.pem') # Get reference to database and collection db = client['travel-sample'] airline_collection = db['airline'] # upsert document function def upsert_document(doc): print("\nUpsert Result: ") try: # key will equal: "airline_8091" key = doc["type"] + "_" + str(doc["id"]) doc['_id'] = key # Amazon DocumentDB uses _id as primary key result = airline_collection.update_one( {'_id': key}, {'$set': doc}, upsert=True ) print(f"Modified count: {result.modified_count}") except Exception as e: print(e) # get document function def get_airline_by_key(key): print("\nGet Result: ") try: result = airline_collection.find_one({'_id': key}) print(result) except Exception as e: print(e) # query for document by callsign def lookup_by_callsign(cs): print("\nLookup Result: ") try: result = airline_collection.find( {'callsign': cs}, {'name': 1, '_id': 0} ) for doc in result: print(doc['name']) except Exception as e: print(e) # Test document airline = { "type": "airline", "id": 8091, "callsign": "CBS", "iata": None, "icao": None, "name": "Couchbase Airways", } upsert_document(airline) get_airline_by_key("airline_8091") lookup_by_callsign("CBS")
有关使用 Python、 Node.js、PHP、Go、Java、C#/.NET、R 和 Ruby 连接到 Amazon DocumentDB 的示例,请参阅以编程方式连接到 Amazon DocumentDB。connect_programmatically.html
选择迁移方法
将数据迁移到 Amazon DocumentDB 时,有两种选择:
注意
Amazon DocumentDB 使用该_id字段作为每个文档的主键。本指南中的迁移方法将 Couchbase 文档密钥存储在字段中_id。对于离线迁移,可通过中的--include-key _id选项完成此操作cbexport。对于在线迁移,这是通过Kafka连接器完成的ProvidedInKeyStrategy。
离线迁移
在以下情况下考虑离线迁移:
停机时间是可以接受的:离线迁移包括停止对源数据库的写入操作,导出数据,然后将其导入到 Amazon DocumentDB。此过程会导致您的应用程序停机。如果您的应用程序或工作负载可以承受这段时间不可用,则离线迁移是一个可行的选择。
迁移较小的数据集或进行概念验证:对于较小的数据集,导出和导入过程所需的时间相对较短,这使得离线迁移成为一种快速而简单的方法。它还非常适合停机时间不太重要的开发、测试和概念验证环境。
简单性是重中之重:使用 cbexport 和 mongoimport 的离线方法通常是最直接的数据迁移方法。它避免了在线迁移方法中涉及的变更数据采集 (CDC) 的复杂性。
无需复制正在进行的更改:如果源数据库在迁移期间未主动接收更改,或者如果在迁移过程中捕获这些更改并将其应用于目标数据库并不重要,则离线方法是合适的。
Couchbase 服务器 6.x 或更早版本
Couchbase 存储桶到亚马逊 DocumentDB 集合
使用 cbexport json --format选项,您可以使用lines或list。
cbexport json \ --cluster <source cluster endpoint> \ --bucket <bucket name> \ --format <lines | list> \ --username <username> \ --password <password> \ --output export.json \ --include-key _id
使用 mongo import 将数据导入到 Amazon DocumentDB 集合中,并使用相应的选项来导入行或列表:
线路:
mongoimport \ --db <database> \ --collection <collection> \ --uri "<Amazon DocumentDB cluster connection string>" \ --ssl \ --sslCAFile global-bundle.pem \ --file export.json
清单:
mongoimport \ --db <database> \ --collection <collection> \ --uri "<Amazon DocumentDB cluster connection string>" \ --ssl \ --sslCAFile global-bundle.pem \ --jsonArray \ --file export.json
Couchbase 服务器 7.0 或更高版本
要执行离线迁移,请使用 cbexport 和 mongoimport 工具:
具有默认范围和默认集合的 Couchbase 存储桶
使用 cbexport json 导出数据,--format选项,您可以使用lines或list。
cbexport json \ --cluster <source cluster endpoint> \ --bucket <bucket name> \ --format <lines | list> \ --username <username> \ --password <password> \ --output export.json \ --include-key _id
使用 mongo import 将数据导入到 Amazon DocumentDB 集合中,并使用相应的选项来导入行或列表:
线路:
mongoimport \ --db <database> \ --collection <collection> \ --uri "<Amazon DocumentDB cluster connection string>" \ --ssl \ --sslCAFile global-bundle.pem \ --file export.json
清单:
mongoimport \ --db <database> \ --collection <collection> \ --uri "<Amazon DocumentDB cluster connection string>" \ --ssl \ --sslCAFile global-bundle.pem \ --jsonArray \ --file export.json
Couchbase 集合到亚马逊 DocumentDB 集合
使用 cbexport json 导出数据--include-data选项导出每个集合。对于该--format选项,您可以使用lines或list。使用--scope-field和--collection-field选项将范围和集合的名称存储在每个 JSON 文档的指定字段中。
cbexport json \ --cluster <source cluster endpoint> \ --bucket <bucket name> \ --include-data <scope name>.<collection name> \ --format <lines | list> \ --username <username> \ --password <password> \ --output export.json \ --include-key _id \ --scope-field "_scope" \ --collection-field "_collection"
由于 cbexport 向每个导出的文档添加了_scope和_collection字段,因此您可以通过搜索和替换或任何您喜欢的方法将其从导出文件中的每个文档中删除。sed
使用 mongoimport 将每个集合的数据导入到 Amazon DocumentDB 集合中,并使用相应的选项来导入行或列表:
线路:
mongoimport \ --db <database> \ --collection <collection> \ --uri "<Amazon DocumentDB cluster connection string>" \ --ssl \ --sslCAFile global-bundle.pem \ --file export.json
清单:
mongoimport \ --db <database> \ --collection <collection> \ --uri "<Amazon DocumentDB cluster connection string>" \ --ssl \ --sslCAFile global-bundle.pem \ --jsonArray \ --file export.json
在线迁移
当您需要最大限度地减少停机时间并且需要近乎实时地将正在进行的更改复制到 Amazon DocumentDB 时,可以考虑进行在线迁移。
请参阅如何从 Couchbase 实时迁移到 Amazon DocumentDB
Couchbase 服务器 6.x 或更早版本
Couchbase 存储桶到亚马逊 DocumentDB 集合
Couchbase 的document.id.strategy参数配置为使用消息键值作为_id字段值(请参阅接收器连接器 ID 策略属性
ConnectorConfiguration: document.id.strategy: 'com.mongodb.kafka.connect.sink.processor.id.strategy.ProvidedInKeyStrategy'
Couchbase 服务器 7.0 或更高版本
具有默认范围和默认集合的 Couchbase 存储桶
Couchbase 的document.id.strategy参数配置为使用消息键值作为_id字段值(请参阅接收器连接器 ID 策略属性
ConnectorConfiguration: document.id.strategy: 'com.mongodb.kafka.connect.sink.processor.id.strategy.ProvidedInKeyStrategy'
Couchbase 集合到亚马逊 DocumentDB 集合
将源连接器配置
ConnectorConfiguration: # add couchbase.collections configuration couchbase.collections: '<scope 1>.<collection 1>, <scope 1>.<collection 2>, ...'
将接收器连接器配置为从每个主题流式传输
ConnectorConfiguration: # remove collection configuration #collection: 'test' # modify topics configuration topics: '<bucket>.<scope 1>.<collection 1>, <bucket>.<scope 1>.<collection 2>, ...' # add topic.override.%s.%s configurations for each topic topic.override.<bucket>.<scope 1>.<collection 1>.collection: '<collection>' topic.override.<bucket>.<scope 1>.<collection 2>.collection: '<collection>'
验证
本节提供了详细的验证流程,用于在迁移到 Amazon DocumentDB 后验证数据的一致性和完整性。无论采用哪种迁移方法,验证步骤都适用。
验证目标中是否存在所有集合
Couchbase 来源
选项 1:查询工作台
SELECT RAW `path` FROM system:keyspaces WHERE `bucket` = '<bucket>'
选项 2:cbq 工具
cbq \ -e <source cluster endpoint> \ -u <username> \ -p <password> \ -q "SELECT RAW `path` FROM system:keyspaces WHERE `bucket` = '<bucket>'"
Amazon DocumentDB 目标
mongosh(请参阅连接到您的 Amazon DocumentDB 集群):
db.getSiblingDB('<database>') db.getCollectionNames()
验证源集群和目标集群之间的文档数量
Couchbase 来源
Couchbase 服务器 6.x 或更早版本
选项 1:查询工作台
SELECT COUNT(*) FROM `<bucket>`
选项 2:cbq
cbq \ -e <source cluster endpoint> \ -u <username> \ -p <password> \ -q "SELECT COUNT(*) FROM `<bucket>`"
Couchbase 服务器 7.0 或更高版本
选项 1:查询工作台
SELECT COUNT(*) FROM `<bucket>`.`<scope>`.`<collection>`
选项 2:cbq
cbq \ -e <source cluster endpoint> \ -u <username> \ -p <password> \ -q "SELECT COUNT(*) FROM `<bucket>`.`<scope>`.`<collection>`"
Amazon DocumentDB 目标
mongosh(请参阅连接到您的 Amazon DocumentDB 集群):
db = db.getSiblingDB('<database>') db.getCollection('<collection>').countDocuments()
比较源集群和目标集群之间的文档
Couchbase 来源
Couchbase 服务器 6.x 或更早版本
选项 1:查询工作台
SELECT META().id as _id, * FROM `<bucket>` LIMIT 5
选项 2:cbq
cbq \ -e <source cluster endpoint> \ -u <username> \ -p <password> \ -q "SELECT META().id as _id, * FROM `<bucket>` LIMIT 5"
Couchbase 服务器 7.0 或更高版本
选项 1:查询工作台
SELECT META().id as _id, * FROM `<bucket>`.`<scope>`.`<collection>` LIMIT 5
选项 2:cbq
cbq \ -e <source cluster endpoint> \ -u <username> \ -p <password> \ -q "SELECT META().id as _id, * FROM `<bucket>`.`<scope>`.`<collection>` LIMIT 5"
Amazon DocumentDB 目标
mongosh(请参阅连接到您的 Amazon DocumentDB 集群):
db = db.getSiblingDB('<database>') db.getCollection('<collection>').find({ _id: { $in: [ <_id 1>, <_id 2>, <_id 3>, <_id 4>, <_id 5> ] } })