レンジ戦略を用いたSharding MongoDB


ハイ👋👋
この記事では、Kubernetes上で動作するMongoデータベースのシャドウのトピックを調査します.私たちが始める前に、あなたが沿って続くことを望むならば、前提条件セクションでリストされたツールをインストールしてくださいSharding Pattern .

必要条件

  • Kubernetes Cluster & kubectl
  • mongosh
  • helm
  • 導入


    KerbernetesクラスタにMongoDBインスタンスをヘルムを使用してインストールしましょう.
    helm repo add bitnami https://charts.bitnami.com/bitnami
    helm install my-mongo bitnami/mongodb-sharded
    
    インストールが完了したら、データベースのルートパスワードとレプリカセットキーを保存します.私が最初にこれをしている間、私は混乱して、きちんと彼らを保存しませんでした.
    コマンドラインでパスワードとレプリカセットキーを印刷するには、次のコマンドを実行します.Windowsでは、Base 64用のPowerShell関数を用意しています.Unix上であれば、base 64にデコードしてください.
    kubectl get secret --namespace default my-release-mongodb-sharded -o jsonpath="{.data.mongodb-root-password}" | base64
    kubectl get secret --namespace default my-release-mongodb-sharded -o j
    

    データベースのシェイディング


    すべてのポッドが実行されていることを確認し、Mongosサーバーへのシェル接続を開始します.
     @denis ➜ ~ kubectl get pods
        NAME                                              READY   STATUS    RESTARTS   AGE
        my-mongo-mongodb-sharded-configsvr-0              1/1     Running   0          3m8s
        my-mongo-mongodb-sharded-configsvr-1              1/1     Running   0          116s
        my-mongo-mongodb-sharded-mongos-c4dd66768-dqlbv   1/1     Running   0          3m8s
        my-mongo-mongodb-sharded-shard0-data-0            1/1     Running   0          3m8s
        my-mongo-mongodb-sharded-shard0-data-1            1/1     Running   0          103s
        my-mongo-mongodb-sharded-shard1-data-0            1/1     Running   0          3m8s
    my-mongo-mongodb-sharded-shard1-data-1            1/1     Running   0          93s
    
    kubectl port-forward --namespace default svc/my-mongo-mongodb-sharded 27017:27017
    # and in another terminal:
    mongosh --host 127.0.0.1 --authenticationDatabase admin -u root -p $MONGODB_ROOT_PASSWORD
    
    sh . status ()を実行すると、2つのMongo shardsを出力します.
    shards
    [
      {
        _id: 'my-mongo-mongodb-sharded-shard-0',
        host: 'my-mongo-mongodb-sharded-shard-0/my-mongo-mongodb-sharded-shard0-data-0.my-mongo-mongodb-sharded-headless.default.svc.cluster.local:27017,my-mongo-mongodb-sharded-shard0-data-1.my-mongo-mongodb-sharded-headless.default.svc.cluster.local:27017',
        state: 1
      },
      {
        _id: 'my-mongo-mongodb-sharded-shard-1',
        host: 'my-mongo-mongodb-sharded-shard-1/my-mongo-mongodb-sharded-shard1-data-0.my-mongo-mongodb-sharded-headless.default.svc.cluster.local:27017,my-mongo-mongodb-sharded-shard1-data-1.my-mongo-mongodb-sharded-headless.default.svc.cluster.local:27017',
        state: 1
      }
    ]
    
    データベースとコレクションの共有を有効にするには、MySense Data DatabaseやMyCountユーザーコレクションにダミーデータを挿入します.このブログ記事の終わりにデータを挿入するためのスクリプトが添付されています.
    [direct: mongos]> sh.enableSharding("my_data")
    {
      ok: 1,
      operationTime: Timestamp(3, 1628345449),
      '$clusterTime': {
        clusterTime: Timestamp(3, 1628345449),
        signature: {
          hash: Binary(Buffer.from("e57c8c37047f7aa170fb59f6b11e22aa65159a30", "hex"), 0),
          keyId: Long("6993682727694237708")
        }
      }
    }
    
    [direct: mongos]> db.my_users.createIndex({"t": 1})
    [direct: mongos]> sh.shardCollection("my_data.my_users", { "t": 1 })
    
    sh.addShardToZone("my-mongo-mongodb-sharded-shard-1", "TSR1")
    sh.addShardToZone("my-mongo-mongodb-sharded-shard-0", "TSR2")
    
    あなたがこれまでそれをしたならば、Congrats、あなたはShardingを可能にしました.
    私たちはキーTに基づいたレンジシェーディングストラテジーを使用するつもりですから、2つのshardを利用できます.
    sh.updateZoneKeyRange("my_data.my_users", {t: 46}, {t: MaxKey()}, "TSR2")
    sh.updateZoneKeyRange("my_data.my_users", {t: MinKey()}, {t: 46}, "TSR1")
    

    注意: TSR 2ゾーンのラベルは間違っています.≤ T < 1000
    sh ()を実行すると、以下の出力が得られます.
    collections: {
      'my_data.my_users': {
        shardKey: { t: 1 },
        unique: false,
        balancing: true,
        chunkMetadata: { shard: 'my-mongo-mongodb-sharded-shard-1', nChunks: 3 },
        chunks: [
          {
            min: { t: MinKey() },
            max: { t: 45 },
            'on shard': 'my-mongo-mongodb-sharded-shard-1',
            'last modified': Timestamp(2, 1)
          },
          {
            min: { t: 46 },
            max: { t: MaxKey() },
            'on shard': 'my-mongo-mongodb-sharded-shard-0',
            'last modified': Timestamp(0, 2)
          }
        ],
        tags: [
          { tag: 'TSR1', min: { t: MinKey() }, max: { t: 46} },
          { tag: 'TSR2', min: { t: 46 }, max: { t: MaxKey() } }
        ]
      }
    
    規則をテストするには、提供されたPythonスクリプトを使用し、Times変数を変更し、さまざまな値で実行します.
    DBを実行できます.MyLesユーザー.shsharddistribution ()を使用して、シャード上のデータ配布を表示します.
    [direct: mongos]> db.my_users.getShardDistribution()
    
    Shard my-mongo-mongodb-sharded-shard-0 at my-mongo-mongodb-sharded-shard-0/my-mongo-mongodb-sharded-shard0-data-0.my-mongo-mongodb-sharded-headless.default.svc.cluster.local:27017,my-mongo-mongodb-sharded-shard0-data-1.my-mongo-mongodb-sharded-headless.default.svc.cluster.local:27017
    {
      data: '144KiB',
      docs: 1667,
      chunks: 1,
      'estimated data per chunk': '144KiB',
      'estimated docs per chunk': 1667
    }
    
    Shard my-mongo-mongodb-sharded-shard-1 at my-mongo-mongodb-sharded-shard-1/my-mongo-mongodb-sharded-shard1-data-0.my-mongo-mongodb-sharded-headless.default.svc.cluster.local:27017,my-mongo-mongodb-sharded-shard1-data-1.my-mongo-mongodb-sharded-headless.default.svc.cluster.local:27017
    {
      data: '195KiB',
      docs: 2336,
      chunks: 3,
      'estimated data per chunk': '65KiB',
      'estimated docs per chunk': 778
    }
    

    より多くの破片を加えること


    クラスタにより多くのshardを追加するには、私たちが行う必要があるのはヘルムアップグレードを実行することです.
    helm upgrade my-mongo bitnami/mongodb-sharded --set shards=3,configsvr.replicas=2,shardsvr.dataNode.replicas=2,mongodbRootPassword=tcDMM5sqNC,replicaSetKey=D6BGM2ixd3
    
    あなたがキーを台無しにするならば😅, 次に、問題を解決するために、これらの手順に従ってオンラインでクラスタを戻すをもたらす.
  • クラスタを2シャードに戻す
  • SSHは古い作業シャードShard 1またはShard 0に入り、環境変数から資格情報を取得します.
  • Kubernetes秘密とMongos Podの資格はアップグレードによって上書きされました、そして、彼らは間違っています!
    MONGODB_ROOT_PASSWORD=tcDMM5sqNC
    MONGODB_ENABLE_DIRECTORY_PER_DB=no
    MONGODB_SYSTEM_LOG_VERBOSITY=0
    MY_MONGO_MONGODB_SHARDED_SERVICE_PORT=27017
    KUBERNETES_SERVICE_HOST=10.245.0.1
    MONGODB_REPLICA_SET_KEY=D6BGM2ixd3
    
    正しいパスワードとレプリカセットキーを保存した後、間違ったレプリカセットのキーを持っているし、それらを削除するshardsに属するボリュームを検索します.私の場合、私は追加した3番目のシャードに属するボリュームを削除するだけです.
    @denis ➜ Downloads kubectl get persistentvolumeclaims
    NAME                                               STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS       AGE
    datadir-my-mongo-mongodb-sharded-configsvr-0       Bound    pvc-8e7fa303-9198-419e-a6c1-8de3e6d89962   8Gi        RWO            do-block-storage   132m
    datadir-my-mongo-mongodb-sharded-configsvr-1       Bound    pvc-6e3bc70f-83a8-4e80-b856-c44a4295be35   8Gi        RWO            do-block-storage   131m
    datadir-my-mongo-mongodb-sharded-shard0-data-0     Bound    pvc-f66647bc-ee3b-4820-b466-a11b197fde74   8Gi        RWO            do-block-storage   132m
    datadir-my-mongo-mongodb-sharded-shard0-data-1     Bound    pvc-62257e91-d461-4ddb-af37-4876d2431703   8Gi        RWO            do-block-storage   131m
    datadir-my-mongo-mongodb-sharded-shard1-data-0     Bound    pvc-9a062ba5-f320-49c9-ae15-d75e8e5f2cf8   8Gi        RWO            do-block-storage   132m
    datadir-my-mongo-mongodb-sharded-shard1-data-1     Bound    pvc-068b04bd-8875-40d7-b47c-40092ceb7973   8Gi        RWO            do-block-storage   130m
    datadir-my-mongo-mongodb-sharded-shard2-data-0     Bound    pvc-93d9a238-ae36-49e1-b0b6-f320baf89373   8Gi        RWO            do-block-storage   73m
    datadir-my-mongo-mongodb-sharded-shard2-data-1     Bound    pvc-b09a8d0d-5012-4f23-8096-a713f3025521   8Gi        RWO            do-block-storage   50m
    @denis ➜ Downloads kubectl get persistentvolumes
    NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                                      STORAGECLASS       REASON   AGE
    pvc-068b04bd-8875-40d7-b47c-40092ceb7973   8Gi        RWO            Delete           Bound    default/datadir-my-mongo-mongodb-sharded-shard1-data-1     do-block-storage            131m
    pvc-321136d8-8a27-45cb-8ed1-8d636c530859   8Gi        RWO            Delete           Bound    default/datadir-my-release-mongodb-sharded-shard2-data-1   do-block-storage            143m
    pvc-42dd7167-5836-4e94-bf42-473c6cea49a4   8Gi        RWO            Delete           Bound    default/datadir-my-release-mongodb-sharded-shard2-data-0   do-block-storage            145m
    pvc-48714777-97b3-4acc-8562-7b69a8e3b488   8Gi        RWO            Delete           Bound    default/datadir-my-release-mongodb-sharded-shard1-data-1   do-block-storage            143m
    pvc-499797e9-a5df-4c7b-a1fb-482c3dca36a6   8Gi        RWO            Delete           Bound    default/datadir-my-release-mongodb-sharded-shard3-data-1   do-block-storage            143m
    pvc-61ec9e04-1bad-4312-ba16-fb24c12efb4b   8Gi        RWO            Delete           Bound    default/datadir-my-release-
    ...
    
    その後、ヘルムアップグレードコマンドを実行し、すべてが動作している場合は、mongosh接続を取得します😀.
    sh ()を実行すると、3番目のシャードが表示されます.
    [
      {
        _id: 'my-mongo-mongodb-sharded-shard-0',
        host: 'my-mongo-mongodb-sharded-shard-0/my-mongo-mongodb-sharded-shard0-data-0.my-mongo-mongodb-sharded-headless.default.svc.cluster.local:27017,my-mongo-mongodb-sharded-shard0-data-1.my-mongo-mongodb-sharded-headless.default.svc.cluster.local:27017',
        state: 1,
        tags: [ 'TSR2' ]
      },
      {
        _id: 'my-mongo-mongodb-sharded-shard-1',
        host: 'my-mongo-mongodb-sharded-shard-1/my-mongo-mongodb-sharded-shard1-data-0.my-mongo-mongodb-sharded-headless.default.svc.cluster.local:27017,my-mongo-mongodb-sharded-shard1-data-1.my-mongo-mongodb-sharded-headless.default.svc.cluster.local:27017',
        state: 1,
        tags: [ 'TSR1' ]
      },
      {
        _id: 'my-mongo-mongodb-sharded-shard-2',
        host: 'my-mongo-mongodb-sharded-shard-2/my-mongo-mongodb-sharded-shard2-data-0.my-mongo-mongodb-sharded-headless.default.svc.cluster.local:27017,my-mongo-mongodb-sharded-shard2-data-1.my-mongo-mongodb-sharded-headless.default.svc.cluster.local:27017',
        state: 1
      }
    ]
    
    次に、シャープルールを更新し、すべての図のように動作します.
    sh.addShardToZone("my-mongo-mongodb-sharded-shard-2", "TSR3")
    sh.removeRangeFromZone("my_data.my_users", {t: 46}, {t: MaxKey()}, "TSR2")
    sh.updateZoneKeyRange("my_data.my_users", {t: 46}, {t 1000}, "TSR2")
    sh.updateZoneKeyRange("my_data.my_users", {t: 1000}, {t: MaxKey()}, "TSR3")
    
    sh . stat ()は次のように表示します.
    chunks: [
        {
          min: { t: MinKey() },
          max: { t: 46 },
          'on shard': 'my-mongo-mongodb-sharded-shard-1',
          'last modified': Timestamp(0, 5)
        },
        {
          min: { t: 46 },
          max: { t: 1000 },
          'on shard': 'my-mongo-mongodb-sharded-shard-0',
          'last modified': Timestamp(3, 4)
        },
        {
          min: { t: 1000 },
          max: { t: MaxKey() },
          'on shard': 'my-mongo-mongodb-sharded-shard-2',
          'last modified': Timestamp(1, 5)
        }
      ],
      tags: [
        { tag: 'TSR1', min: { t: MinKey() }, max: { t: 46 } },
        { tag: 'TSR2', min: { t: 46 }, max: { t: 1000 } },
        { tag: 'TSR3', min: { t: 1000 }, max: { t: MaxKey() } }
      ]
    }
    

    結論


    シェーディングMongoDB最初に威嚇することができますが、事前にいくつかの練習では、それを行うことができます!シャープがあなたのために動作しない場合は、することができますConvert Sharded Cluster to Replica Set , しかし、いくつかのバックアップを用意してください.
    読書ありがとう📚 そして、幸せなハッキング!🔩🔨

    パワーシェル関数


    function global:Convert-From-Base64 {
      [CmdletBinding()]
      [Alias('base64')]
      param (
        [parameter(ValueFromPipeline,Mandatory=$True,Position=0)]
        [string] $EncodedText
      )
      process {
        [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($EncodedText))
      }
    }
    

    Pythonスクリプト


    import random
    
    import pymongo
    
    
    def do_stuff():
        client = pymongo.MongoClient("mongodb://root:[email protected]:27017/?directConnection=true&serverSelectionTimeoutMS=2000")
        col = client.my_data.my_users
    
        usernames = ["dovahkiin", "rey", "dey", "see", "mee", "rollin", "they", "hating"]
        hobbies = ["coding", "recording", "streaming", "batman", "footbal", "sports", "mathematics"]
        ages = [18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28]
        # times = [12, 14, 15, 23, 45, 32, 20]
        times = [47, 80, 93, 49, 96, 43]
    
        buffer = []
        for _ in range(1_000):
            first = random.choice(usernames).capitalize()
            mid = random.choice(usernames).capitalize()
            last = random.choice(usernames).capitalize()
            buffer.append(pymongo.InsertOne({
                "name": f"{first} '{mid}' {last}",
                "age": random.choice(ages),
                "hobbies": random.choice(hobbies),
                "t": random.choice(times)
            }))
        col.bulk_write(buffer)
    
    
    if __name__ == '__main__':
        do_stuff()
    
    参考文献
    https://bitnami.com/stack/mongodb-sharded/helm
    https://docs.microsoft.com/en-us/azure/architecture/patterns/sharding
    https://docs.mongodb.com/manual/core/zone-sharding/
    https://docs.mongodb.com/manual/core/ranged-sharding/
    https://docs.mongodb.com/manual/reference/method/sh.updateZoneKeyRange/
    https://docs.mongodb.com/v5.0/core/sharding-choose-a-shard-key/
    スターラインで作成される青いベクトルwww.freepik.com