지속적 통합과 지속적 배포는 이제 일반적인 소프트웨어 개발 관행입니다. 데이터베이스의 세계에서 이는 온디맨드, 상태 저장, 임시 환경이 필요하다는 의미로 해석됩니다.
상태 비저장 환경 프로비저닝은 특정 데이터 소스에 종속되지 않습니다. CI 환경에서 테스트하려는 코드를 실행하기만 하면 됩니다. 이는 대부분의 CI/CD 도구의 기본이며 이 문서에서는 다루지 않습니다.
조금 더 어려운 부분은 애플리케이션을 제대로 테스트해야 하는 종속성에서 비롯되는데, 이를 종종 외부 서비스라고 합니다. 카우치베이스도 그중 하나입니다. 예를 들어 Docker 컨테이너를 사용하거나 테스트 인프라에서 호스팅하거나 서비스형 외부 솔루션을 사용하는 등 다양한 방법이 있습니다. 테스트를 실행하는 동안 사용할 수만 있다면 어떤 방식이든 상관없습니다. 환경 변수를 사용하여 이러한 인스턴스를 참조하는 것이 좋습니다.
이러한 서비스가 Couchbase 무료 티어 인스턴스 또는 Docker 컨테이너와 같이 실행 중이라고 가정하면 다음 단계는 이러한 서비스가 올바르게 구성되고 테스트에 필요한 데이터가 시딩되었는지 확인하는 것입니다.
얼마 전에 GitHub 작업의 Couchbase 셸. 여기서는 GitHub Actions와 함께 Couchbase Shell을 사용하는 기본 사항을 설명했지만, 대부분의 CI/CD 솔루션에도 적용할 수 있습니다. 오늘은 여기서 더 나아가 온디맨드 환경에서 클러스터 또는 클러스터의 요소를 복제하는 데 유용한 몇 가지 스크립트를 보여드리고자 합니다.
Couchbase Shell을 사용하여 환경 복제하기
카우치베이스 셸을 사용할 때 어떤 작업을 하고 싶을 때 가장 먼저 떠오르는 것이 바로 그런 기능이 있나요? 현재로서는 무언가를 복제할 수 있는 함수가 없습니다. 사용 가능한 대부분의 함수는 API 기능을 반영하며 현재로서는 복제 API가 없습니다. 하지만 스크립트를 작성할 수 있는 기능이 있으므로 직접 만들 수도 있습니다!
데이터베이스를 관리할 때 가장 먼저 떠오르는 것은 구조와 스키마를 다시 만드는 일입니다. Couchbase는 스키마가 없기 때문에 소스 클러스터의 기존 버킷, 범위, 컬렉션 및 인덱스로만 구성됩니다. 첫 번째 단계는 나중에 다시 가져올 수 있도록 해당 구조를 내보내는 것입니다. 이 함수는 모든 버킷을 나열한 다음 내부 범위와 컬렉션을 나열하고 배열에 추가합니다. 그런 다음 모든 인덱스를 나열하고 출력 JSON에 추가합니다.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# Exports all buckets, scopes, collections and indexes # for the given cluster def export-cluster-struct [ source: string # The cluster to export ] { mut export = [] let buckets = buckets --clusters $source # List the buckets of the given cluster for bucket in $buckets { mut scope_structs = [] let scopes = scopes --clusters $source --bucket $bucket.name for scope in $scopes { let collections = (collections --clusters $source --bucket $bucket.name --scope $scope.scope | reject -i cluster) $scope_structs ++= [{ scope: $scope.scope, collections: $collections }] } # Merge the scopes with the bucket object and add it to the export array let buc = ( $bucket | merge {scopes: $scope_structs } ) $export ++= [ $buc ] } let indexes = query indexes --definitions --disable-context --clusters $source let output = { buckets: $export, indexes: $indexes } return $output } |
이는 내부적으로 Couchbase Shell이 이식성이 있고(즉, Linux, Windows 또는 OS X에서 동일한 방식으로 작동하므로 다양한 OS를 지원해야 하는 CI/CD 스크립트에 적합), 모든 구조 데이터를 DataFrame으로 간주하여 JSON을 매우 쉽게 조작할 수 있는 새로운 유형의 셸인 Nushell을 사용하기 때문에 가능한 일입니다.
사용해 보려면 다음을 실행하세요. cbsh, 를 클릭한 다음 함수가 포함된 파일을 소싱하세요. 저에게는 ci_scripts.nu. 내 cbsh 구성에 이미 다음과 같은 클러스터가 구성되어 있습니다. local
|
1 2 3 4 |
Laurent Doguin at local in travel-sample.inventory._default > source ci-scripts.nu Laurent Doguin at local in travel-sample.inventory._default > export-cluster-struct local | save local-cluster-export.json |
이제 다음을 열면 local-cluster-export.json, 를 클릭하면 클러스터의 구조를 확인할 수 있습니다:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 |
{ "buckets": [ { "cluster": "local", "name": "travel-sample", "type": "couchbase", "replicas": 0, "min_durability_level": "none", "ram_quota": 209715200, "flush_enabled": false, "cloud": false, "max_expiry": 0, "scopes": [ { "scope": "inventory", "collections": [ { "collection": "airport", "max_expiry": "inherited" }, { "collection": "airline", "max_expiry": "inherited" }, { "collection": "route", "max_expiry": "inherited" }, { "collection": "landmark", "max_expiry": "inherited" }, { "collection": "hotel", "max_expiry": "inherited" } ] }, { "scope": "tenant_agent_00", "collections": [ { "collection": "users", "max_expiry": "inherited" }, { "collection": "bookings", "max_expiry": "inherited" } ] }, { "scope": "tenant_agent_01", "collections": [ { "collection": "users", "max_expiry": "inherited" }, { "collection": "bookings", "max_expiry": "inherited" } ] }, { "scope": "tenant_agent_02", "collections": [ { "collection": "users", "max_expiry": "inherited" }, { "collection": "bookings", "max_expiry": "inherited" } ] }, { "scope": "tenant_agent_03", "collections": [ { "collection": "users", "max_expiry": "inherited" }, { "collection": "bookings", "max_expiry": "inherited" } ] }, { "scope": "tenant_agent_04", "collections": [ { "collection": "users", "max_expiry": "inherited" }, { "collection": "bookings", "max_expiry": "inherited" } ] }, { "scope": "_default", "collections": [ { "collection": "_default", "max_expiry": "inherited" } ] }, { "scope": "_system", "collections": [ { "collection": "_query", "max_expiry": "" }, { "collection": "_mobile", "max_expiry": "" } ] } ] } ], "indexes": [ { "bucket": "travel-sample", "scope": "_system", "collection": "_query", "name": "#primary", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE PRIMARY INDEX `#primary` ON `travel-sample`.`_system`.`_query`", "cluster": "local" }, { "bucket": "travel-sample", "scope": "_default", "collection": "_default", "name": "def_airportname", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE INDEX `def_airportname` ON `travel-sample`(`airportname`) WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "_default", "collection": "_default", "name": "def_city", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE INDEX `def_city` ON `travel-sample`(`city`) WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "_default", "collection": "_default", "name": "def_faa", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE INDEX `def_faa` ON `travel-sample`(`faa`) WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "_default", "collection": "_default", "name": "def_icao", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE INDEX `def_icao` ON `travel-sample`(`icao`) WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "inventory", "collection": "airline", "name": "def_inventory_airline_primary", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE PRIMARY INDEX `def_inventory_airline_primary` ON `travel-sample`.`inventory`.`airline` WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "inventory", "collection": "airport", "name": "def_inventory_airport_airportname", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE INDEX `def_inventory_airport_airportname` ON `travel-sample`.`inventory`.`airport`(`airportname`) WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "inventory", "collection": "airport", "name": "def_inventory_airport_city", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE INDEX `def_inventory_airport_city` ON `travel-sample`.`inventory`.`airport`(`city`) WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "inventory", "collection": "airport", "name": "def_inventory_airport_faa", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE INDEX `def_inventory_airport_faa` ON `travel-sample`.`inventory`.`airport`(`faa`) WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "inventory", "collection": "airport", "name": "def_inventory_airport_primary", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE PRIMARY INDEX `def_inventory_airport_primary` ON `travel-sample`.`inventory`.`airport` WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "inventory", "collection": "hotel", "name": "def_inventory_hotel_city", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE INDEX `def_inventory_hotel_city` ON `travel-sample`.`inventory`.`hotel`(`city`) WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "inventory", "collection": "hotel", "name": "def_inventory_hotel_primary", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE PRIMARY INDEX `def_inventory_hotel_primary` ON `travel-sample`.`inventory`.`hotel` WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "inventory", "collection": "landmark", "name": "def_inventory_landmark_city", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE INDEX `def_inventory_landmark_city` ON `travel-sample`.`inventory`.`landmark`(`city`) WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "inventory", "collection": "landmark", "name": "def_inventory_landmark_primary", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE PRIMARY INDEX `def_inventory_landmark_primary` ON `travel-sample`.`inventory`.`landmark` WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "inventory", "collection": "route", "name": "def_inventory_route_primary", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE PRIMARY INDEX `def_inventory_route_primary` ON `travel-sample`.`inventory`.`route` WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "inventory", "collection": "route", "name": "def_inventory_route_route_src_dst_day", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE INDEX `def_inventory_route_route_src_dst_day` ON `travel-sample`.`inventory`.`route`(`sourceairport`,`destinationairport`,(distinct (array (`v`.`day`) for `v` in `schedule` end))) WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "inventory", "collection": "route", "name": "def_inventory_route_schedule_utc", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE INDEX `def_inventory_route_schedule_utc` ON `travel-sample`.`inventory`.`route`(array (`s`.`utc`) for `s` in `schedule` end) WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "inventory", "collection": "route", "name": "def_inventory_route_sourceairport", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE INDEX `def_inventory_route_sourceairport` ON `travel-sample`.`inventory`.`route`(`sourceairport`) WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "_default", "collection": "_default", "name": "def_name_type", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE INDEX `def_name_type` ON `travel-sample`(`name`) WHERE (`_type` = \"User\") WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "_default", "collection": "_default", "name": "def_primary", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE PRIMARY INDEX `def_primary` ON `travel-sample` WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "_default", "collection": "_default", "name": "def_route_src_dst_day", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE INDEX `def_route_src_dst_day` ON `travel-sample`(`sourceairport`,`destinationairport`,(distinct (array (`v`.`day`) for `v` in `schedule` end))) WHERE (`type` = \"route\") WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "_default", "collection": "_default", "name": "def_schedule_utc", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE INDEX `def_schedule_utc` ON `travel-sample`(array (`s`.`utc`) for `s` in `schedule` end) WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "_default", "collection": "_default", "name": "def_sourceairport", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE INDEX `def_sourceairport` ON `travel-sample`(`sourceairport`) WITH { \"defer_build\":true }", "cluster": "local" }, { "bucket": "travel-sample", "scope": "_default", "collection": "_default", "name": "def_type", "status": "Ready", "storage_mode": "memory_optimized", "replicas": 0, "definition": "CREATE INDEX `def_type` ON `travel-sample`(`type`) WITH { \"defer_build\":true }", "cluster": "local" } ] } |
이 테스트의 목적을 위해 나중에 다시 가져오기 위해 해당 버킷을 삭제했습니다: 버킷 드롭 여행 샘플.
다음 논리적 단계는 이 파일을 입력으로 받아 다른 클러스터에서 전체 구조를 다시 생성하는 함수를 만드는 것입니다:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# Import all buckets, scopes and collections structure # in the given cluster def import-cluster-struct [ destination: string # The cluster to import ] { let structure = $in # Assigning the piped structure to a variable let buckets = $structure.buckets for bucket in $buckets { $bucket | _create-bucket-definition $destination for scope in ($bucket.scopes | where not ( $it.scope | str starts-with "_" ) ) { print $"Create scope ($destination)_($bucket.name)_($scope.scope)" scopes create --clusters $destination --bucket $bucket.name $scope.scope for col in $scope.collections { print $"Create collection ($destination)_($bucket.name)_($scope.scope)_($col.collection)" collections create --clusters $destination --bucket $bucket.name --scope $scope.scope $col.collection } } } let indexes = $structure.indexes $indexes | _create-indexes $destination # Nushell allows you to use other functions you created } def _create-indexes [ destination: string # the cluster where to create indexes ] { let indexes = $in for index in $indexes { print $"Recreating index ($index.name) on cluster ($destination) with: " print $index.definition query $index.definition --disable-context --clusters $destination } } |
이제 해당 함수를 실행합니다:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
Laurent Doguin at local in travel-sample.inventory._default > open local-cluster-export.json | import-cluster-struct capella Laurent Doguin at local in travel-sample.inventory._default > open local-cluster-export.json | import-cluster-struct local Create Bucket local_travel-sample with 200 quota, type couchbase, 0 replicas, none durability, 0 expiry Create scope local_travel-sample_inventory Create collection local_travel-sample_inventory_airport Create collection local_travel-sample_inventory_airline Create collection local_travel-sample_inventory_route Create collection local_travel-sample_inventory_landmark Create collection local_travel-sample_inventory_hotel Create scope local_travel-sample_tenant_agent_00 Create collection local_travel-sample_tenant_agent_00_users Create collection local_travel-sample_tenant_agent_00_bookings Create scope local_travel-sample_tenant_agent_01 Create collection local_travel-sample_tenant_agent_01_users Create collection local_travel-sample_tenant_agent_01_bookings Create scope local_travel-sample_tenant_agent_02 Create collection local_travel-sample_tenant_agent_02_users Create collection local_travel-sample_tenant_agent_02_bookings Create scope local_travel-sample_tenant_agent_03 Create collection local_travel-sample_tenant_agent_03_users Create collection local_travel-sample_tenant_agent_03_bookings Create scope local_travel-sample_tenant_agent_04 Create collection local_travel-sample_tenant_agent_04_users Create collection local_travel-sample_tenant_agent_04_bookings Recreating index #primary on cluster local with: CREATE PRIMARY INDEX `#primary` ON `travel-sample`.`_system`.`_query` Recreating index def_airportname on cluster local with: CREATE INDEX `def_airportname` ON `travel-sample`(`airportname`) WITH { "defer_build":true } Recreating index def_city on cluster local with: CREATE INDEX `def_city` ON `travel-sample`(`city`) WITH { "defer_build":true } Recreating index def_faa on cluster local with: CREATE INDEX `def_faa` ON `travel-sample`(`faa`) WITH { "defer_build":true } Recreating index def_icao on cluster local with: CREATE INDEX `def_icao` ON `travel-sample`(`icao`) WITH { "defer_build":true } Recreating index def_inventory_airline_primary on cluster local with: CREATE PRIMARY INDEX `def_inventory_airline_primary` ON `travel-sample`.`inventory`.`airline` WITH { "defer_build":true } Recreating index def_inventory_airport_airportname on cluster local with: CREATE INDEX `def_inventory_airport_airportname` ON `travel-sample`.`inventory`.`airport`(`airportname`) WITH { "defer_build":true }Recreating index def_inventory_airport_city on cluster local with: CREATE INDEX `def_inventory_airport_city` ON `travel-sample`.`inventory`.`airport`(`city`) WITH { "defer_build":true } Recreating index def_inventory_airport_faa on cluster local with: CREATE INDEX `def_inventory_airport_faa` ON `travel-sample`.`inventory`.`airport`(`faa`) WITH { "defer_build":true } Recreating index def_inventory_airport_primary on cluster local with: CREATE PRIMARY INDEX `def_inventory_airport_primary` ON `travel-sample`.`inventory`.`airport` WITH { "defer_build":true } Recreating index def_inventory_hotel_city on cluster local with: CREATE INDEX `def_inventory_hotel_city` ON `travel-sample`.`inventory`.`hotel`(`city`) WITH { "defer_build":true } Recreating index def_inventory_hotel_primary on cluster local with: CREATE PRIMARY INDEX `def_inventory_hotel_primary` ON `travel-sample`.`inventory`.`hotel` WITH { "defer_build":true } Recreating index def_inventory_landmark_city on cluster local with: CREATE INDEX `def_inventory_landmark_city` ON `travel-sample`.`inventory`.`landmark`(`city`) WITH { "defer_build":true } Recreating index def_inventory_landmark_primary on cluster local with: CREATE PRIMARY INDEX `def_inventory_landmark_primary` ON `travel-sample`.`inventory`.`landmark` WITH { "defer_build":true } Recreating index def_inventory_route_primary on cluster local with: CREATE PRIMARY INDEX `def_inventory_route_primary` ON `travel-sample`.`inventory`.`route` WITH { "defer_build":true } Recreating index def_inventory_route_route_src_dst_day on cluster local with: CREATE INDEX `def_inventory_route_route_src_dst_day` ON `travel-sample`.`inventory`.`route`(`sourceairport`,`destinationairport`,(distinct (array (`v`.`day`) for `v` in `schedule` end))) WITH { "defer_build":true } Recreating index def_inventory_route_schedule_utc on cluster local with: CREATE INDEX `def_inventory_route_schedule_utc` ON `travel-sample`.`inventory`.`route`(array (`s`.`utc`) for `s` in `schedule` end) WITH { "defer_build":true } Recreating index def_inventory_route_sourceairport on cluster local with: CREATE INDEX `def_inventory_route_sourceairport` ON `travel-sample`.`inventory`.`route`(`sourceairport`) WITH { "defer_build":true } Recreating index def_name_type on cluster local with: CREATE INDEX `def_name_type` ON `travel-sample`(`name`) WHERE (`_type` = "User") WITH { "defer_build":true } Recreating index def_primary on cluster local with: CREATE PRIMARY INDEX `def_primary` ON `travel-sample` WITH { "defer_build":true } Recreating index def_route_src_dst_day on cluster local with: CREATE INDEX `def_route_src_dst_day` ON `travel-sample`(`sourceairport`,`destinationairport`,(distinct (array (`v`.`day`) for `v` in `schedule` end))) WHERE (`type` = "route") WITH { "defer_build":true } Recreating index def_schedule_utc on cluster local with: CREATE INDEX `def_schedule_utc` ON `travel-sample`(array (`s`.`utc`) for `s` in `schedule` end) WITH { "defer_build":true } Recreating index def_sourceairport on cluster local with: CREATE INDEX `def_sourceairport` ON `travel-sample`(`sourceairport`) WITH { "defer_build":true } Recreating index def_type on cluster local with: CREATE INDEX `def_type` ON `travel-sample`(`type`) WITH { "defer_build":true } |
이제 한 클러스터에서 다른 클러스터로 데이터 구조를 내보내고 가져올 수 있는 함수가 완성되었습니다. 이것은 좋은 출발점이지만, 데이터를 다시 가져오는 방법이나 세분성에 대한 질문이 여전히 남아 있습니다. 또한 전체 클러스터를 내보내고 가져오고 싶지 않을 수도 있습니다.
Nushell을 사용하면 데이터 프레임을 필터링할 수 있으므로 가져올 버킷을 필터링하는 것은 매우 쉽습니다:
|
1 2 |
Laurent Doguin at local in travel-sample.inventory._default > open local-cluster-export.json | { buckets: ( $in.buckets | where name == 'travel-sample'), indexes :( $in.indexes | where bucket == 'travel-sample') } |
이렇게 하면 버킷 이름이 여행 샘플 및 이 버킷에 대한 인덱스.
이제 기본적인 클러스터 구조를 관리할 준비가 완료되었습니다. 데이터는 어떻게 가져오나요? 대부분의 키/값 연산은 물론 INSERT/UPSERT 쿼리도 지원하므로 cbsh로 데이터를 가져올 수 있는 방법은 여러 가지가 있습니다. 그리고 문서 가져오기 명령. 사용법은 매우 간단하며 식별된 ID 필드가 있는 행 목록만 있으면 됩니다. 이 목록은 Nushell용 데이터 프레임으로 변환할 수 있는 모든 것(XML, CSV, TSV, Parquet 등)이 될 수 있습니다. 물론 Couchbase SQL++ 쿼리의 JSON 파일일 수도 있습니다. 다음은 쿼리 결과를 파일에 저장하고 해당 파일을 컬렉션으로 다시 가져오는 예제입니다:
|
1 2 3 4 5 6 7 8 |
# Save file content to filename let filename = $"temp_($src_bucket)_($src_scope)_($src_collection).json" let query = "SELECT meta().id as meta_id, meta().expiration as expiration, c.* FROM `" + $src_bucket + "`." + $src_scope + "." + $src_collection + " c" query --disable-context --clusters $p.src $query | save -f $filename # Import the file content and print the results print $"Import collection content from ($src)_($src_bucket)_($src_scope)_($src_collection) to ($dest)_($dest_bucket)_($dest_scope)_($dest_collection)" print ( doc import --bucket $p.dest_bucket --scope $p.dest_scope --collection $p.dest_collection --clusters $p.dest --id-column meta_id $filename ) |
이는 하나의 구체적인 예시이지만 스크립팅 언어 사용의 요점은 자신만의 것으로 만드는 것입니다. 더 완전한 예제는 다음에서 찾을 수 있습니다. 이 깃허브 요점. 소스 및 대상에 대한 환경 변수를 지원하며 클러스터의 모든 버킷, 특정 버킷, 범위 또는 컬렉션을 복제할지 여부를 결정할 수 있습니다.
주저하지 마시고 여기 또는 다음에 의견을 남겨 주세요. 불화, 를 통해 글로벌 카우치베이스 경험을 개선하기 위한 제안을 항상 찾고 있습니다.