Tous les produits
Search
Centre de documentation

ApsaraDB for MongoDB:Impact du chiffrement SSL sur les performances de l'instance

Dernière mise à jour :Aug 08, 2026

Évaluez l'impact du chiffrement SSL sur les performances d'une instance ApsaraDB for MongoDB en mesurant le temps d'établissement de la connexion et la latence des requêtes, avec et sans activation du SSL.

Environnement de test

Créez une instance ECS et une instance ApsaraDB for MongoDB. Pour plus d'informations, consultez les rubriques Créer une instance de type Replica Set et Créer et gérer une instance ECS dans la console (version express).

Le test utilise les configurations suivantes :

  • Instance ApsaraDB for MongoDB

    • Architecture de l'instance : instance de type Replica Set

    • Nombre de nœuds primaires et secondaires : trois nœuds

    • Nombre de nœuds en lecture seule : un nœud

    • Spécifications de l'instance : 1 cœur et 2 Go de mémoire (usage général)

    • Version de l'instance : MongoDB 4.2

  • Instance ECS

    • Type d'instance : ecs.e-c1m2.large (2 cœurs et 4 Go de mémoire)

Méthode de test

Importation des données de test

Yahoo! Cloud Serving Benchmark (YCSB) permet d'importer 1 000 000 d'entrées dans une collection nommée usertable au sein d'une base de données intitulée ycsb. Exécutez la commande suivante pour importer les entrées :

./bin/ycsb load mongodb -s -p workload=site.ycsb.workloads.CoreWorkload -p recordcount=1000000 -p mongodb.url="mongodb://root:******@dds-bp103175eafac****.mongodb.rds.aliyuncs.com:3717,dds-bp103175eafac****.mongodb.rds.aliyuncs.com:3717,dds-bp103175eafac****.mongodb.rds.aliyuncs.com:3717/admin?readPreference=secondary&replicaSet=mgset-82894753" -threads 8

La collection générée par YCSB présente la structure suivante :

{
  "_id": "user1352498093671118016",
  "field1": "BinData(0,\"L1s/KS8+MlYhISUuIz8qNVx9PTRuNiooNlolPVMzJCE0ODNuP15zLjB6NSU4LV0pPC98LkovOFttOyQkL1chNV8tOlxrKlstPkp3IzkiLTcuLU93ITRqOzEwPScsIEx5L1o5JQ==\")",
  "field0": "BinData(0,\"I0I/NDAmNUkrLFA3PEA5IEI3KC4qKEJ1LCc6JV8rJlo7KUR3MDRqMk95KjhoIlUjLy1qMls9OFU7PTpuKTZsNlUpMVYvNSI4KDlwK1trIUpnMlInKSAmNDg8LSpmOl85PkozMA==\")",
  "field7": "BinData(0,\"NzxyPjUkNiYsOEp1MUIpIDA0M1U/JE1nMjMmODhkIko/LEh1NSRqKl1jKDBqJjMqMiw8PSc6KjgsNEwrLFkpKFh9OzQ+MS86LiB4P1oxLVxjIiQgMCdsM0AhO0QzNTFqI1dpMw==\")",
  "field6": "BinData(0,\"MVhpIj1uI0RlJ1AtP0t/LkAxMVp9MlU3KFJpK0Z3M0M/OE55IFBhPyA6Njp+L1tnJjh4Iic4K1F/Oi9gKz44PFFpPE5jNydqKUJrPyV4KDY2LDd0Nic6PC9wPDhgNykwOj10Iw==\")",
  "field9": "BinData(0,\"OEA/NDRwLilwLzVoMz5oIzVuLStoPlF9NVU5MVd3PDUkPV0nPl07OU05LkYnKDQ8L0VrIkwlJDg+NCRuIitoNjV4PkM9NCt0LyE4PCFkKUI/LVwxKjdsMkgnICsgKFQrJit8Lg==\")",
  "field8": "BinData(0,\"P0J/P0ozMCBwIjJwP0IpJUMlPkhhIkI3MU91OjUmMFM9NEBhJD8+OEdpJDh2OyxmMCQkKUgnJjYoKC0kKVMnKTQuODp6JjVwKSRwI1FhJy88PVAhPiE2OCMsKlYvJF1xOEUrJA==\")",
  "field3": "BinData(0,\"Mjc6KE4zJTEuJCJ4P18lNCZ4NkAtKTAwLFUvMDEsOzUkIEs3MVEzKT4mL1Q5IVF9N0N3O1snIUZ1L0k9IUY7IV8nNiQ+KTJ0I097Llg1MjE0PCQ4KDV2KzYsIDtwNzhuKkQrMA==\")",
  "field2": "BinData(0,\"Jit6L0olLTByJzpuPygyKSE8Li9iK00xIig4PVQhKTBqLkI/O0N9Izs+NVk/ISVmIy14Nko3NyxoI1Z1Pyo4JVt/MylsK1t9PS9yP1kzJFMjPF43P1l5P1xtPDAqLF57IiAsPQ==\")",
  "field5": "BinData(0,\"NSd2NiskPzcmITU4Oz58NzliP0ZpOz5wKiI0OVhlNDx0PlV1OllnNzJiOyMmOF45IEg7OD90KUZnP0g5OUJzK0M/OyN4O15lPzA6LTUgNUw9NDVoL0QrOTssISQ2KCw6KUJlKg==\")",
  "field4": "BinData(0,\"NDNkKjFuPyxsJzEmNzMqLVJzL0YpMTNwMjs8MTRiNEYtLE05P0I9NEU1LS4yNEFpNjUsOUs9JEs1IU5jOF5vIjpiNTMuKSY6K0s1LDp2JEp9KyFiIS1+J1U/LkoxMEp5OzJiIw==\")"
}

Exécution d'un script de test

YCSB ne prend pas en charge les tests de charge avec le chiffrement SSL activé. Utilisez plutôt le script Python suivant.

import time
import pymongo
import datetime
import logging as log
from functools import wraps

log.basicConfig(
    level=log.INFO, format='%(asctime)s - [line %(lineno)d] : %(levelname)s - %(message)s')
console = log.StreamHandler()
console.setLevel(log.INFO)
formatter = log.Formatter(
    '%(asctime)s - [line %(lineno)d] : %(levelname)s - %(message)s')
console.setFormatter(formatter)

def time_recorder():
    def inner(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            start_time = time.time()
            result = func(*args, **kwargs)
            end_time = time.time()
            elapsed_time = (end_time - start_time) * 1000

            print_latency = kwargs.get("print_latency", False)
            return_latency = kwargs.get("return_latency", False)

            if print_latency:
                log.info(
                    f"Function {func.__name__} took {elapsed_time:.4f} millseconds to execute.")

            if return_latency:
                return result, elapsed_time
            return result
        return wrapper
    return inner

@time_recorder()
def build_client_without_ssl(**kwargs):
    client = pymongo.MongoClient(
        "mongodb://root:******@dds-bp103175eafac****.mongodb.rds.aliyuncs.com:3717,dds-bp103175eafac****.mongodb.rds.aliyuncs.com:3717,dds-bp103175eafac****.mongodb.rds.aliyuncs.com:3717/admin?readPreference=secondary&replicaSet=mgset-82894753")
    return client

@time_recorder()
def build_client_with_ssl(**kwargs):
    client = pymongo.MongoClient(
        "mongodb://root:******@dds-bp103175eafac****.mongodb.rds.aliyuncs.com:3717,dds-bp103175eafac****.mongodb.rds.aliyuncs.com:3717,dds-bp103175eafac****.mongodb.rds.aliyuncs.com:3717/admin?readPreference=secondary&replicaSet=mgset-82894753&tls=true&tlsAllowInvalidHostnames=true&tlsCAFile=/root/ApsaraDB-CA-Chain.pem")
    return client

@time_recorder()
def find_one(client, **kwargs):
    client["ycsb"]["usertable"].find_one()

def test_connection():
    client = build_client_without_ssl(print_latency=True)
    find_one(client)

    client = build_client_with_ssl(print_latency=True)
    find_one(client)

test_connection()

@time_recorder()
def test(with_ssl=False, repeat=5000, **kwargs):
    log.info(f"test, with_ssl: {with_ssl}, repeat: {repeat}")
    ssl_suffix = "without-ssl"
    if with_ssl:
        ssl_suffix = "with-ssl"
    suffix = f"{repeat}-{ssl_suffix}.log"
    only_connection_file = f"only-connection-{suffix}"
    first_query_file = f"first-query-{suffix}"
    connection_and_first_query_file = f"connection-and-first-query-{suffix}"

    only_connection_f = open(only_connection_file, 'w')
    first_query_f = open(first_query_file, 'w')
    connection_and_first_query_f = open(connection_and_first_query_file, 'w')

    for _ in range(repeat):
        client = None
        connection_latency = 0

        if with_ssl:
            client, connection_latency = build_client_with_ssl(
                return_latency=True)
        else:
            client, connection_latency = build_client_without_ssl(
                return_latency=True)

        _, query_latency = find_one(client, return_latency=True)

        only_connection_f.write(f"{connection_latency}\n")
        first_query_f.write(f"{query_latency}\n")
        connection_and_first_query_f.write(f"{connection_latency + query_latency}\n")

    only_connection_f.close()
    first_query_f.close()
    connection_and_first_query_f.close()

    log.info(f"test end, write to {only_connection_file}, {first_query_file} and {connection_and_first_query_file}")

test(False, 5000, print_latency=True)
test(True, 5000, print_latency=True)

@time_recorder()
def run(client, log_file, repeat=5000, **kwargs):
    start = time.time()
    log.info(f"start to query, repeat: {repeat}")

    with open(log_file, 'w') as f:
        for _ in range(repeat):
            latency = find_one(client, return_latency=True)
            f.write(f"{latency}\n")

    end = time.time()
    total = (end - start) * 1000
    avg = total / repeat
    log.info(
        f"end query, repeat: {repeat}, total: {total} millseconds, avg: {avg} millseconds")

client = build_client_without_ssl()
run(client, "without-ssl.log")

client = build_client_with_ssl()
run(client, "with-ssl.log")

Modifiez les paramètres suivants selon vos besoins :

  • client : remplacez la chaîne de connexion, le nom d'utilisateur et le mot de passe dans pymongo.MongoClient() par les valeurs réelles de votre instance ApsaraDB for MongoDB.

  • repeat : nombre d'itérations de test. La valeur par défaut est 5 000. Ajustez cette valeur si nécessaire.

Le script génère les métriques suivantes :

  • only-connection : temps nécessaire à l'établissement d'une connexion.

  • first-query : durée de la première requête après l'établissement d'une connexion.

  • connection-and-first-query : durée totale allant de l'établissement de la connexion à la fin de la première requête. Cette valeur correspond à la somme de only-connection et de first-query.

  • latency : durée moyenne de 5 000 requêtes lors de la réutilisation du client spécifié par pymongo.MongoClient().

Résultats des tests

Le tableau ci-dessous présente les valeurs moyennes obtenues sur 5 000 itérations.

Élément

Temps consommé avec le chiffrement SSL désactivé (ms)

Temps consommé avec le chiffrement SSL activé (ms)

Temps consommé pour établir une connexion

3,7009

19,8515

Durée de la première requête après l'établissement d'une connexion

20,7456

43,5884

Durée totale entre l'établissement de la connexion et la fin de la première requête

24,4465

63,4399

Durée moyenne des requêtes lors de la réutilisation du client spécifié

0,7506

0,7643

La différence de performance entre les connexions avec et sans SSL réside principalement dans l'établissement de la connexion. Lorsque les connexions existantes sont réutilisées, les durées moyennes des requêtes sont pratiquement identiques. Les raisons principales sont les suivantes :

  • Transport Layer Security (TLS) ajoute un temps supplémentaire d'aller-retour (RTT) lors de l'établissement de la connexion.

    Grâce au pooling de connexions, ce coût RTT est amorti sur l'ensemble des connexions. La réutilisation d'un client existant après l'activation du SSL minimise ainsi la surcharge liée à la négociation TLS.

  • Le chiffrement et le déchiffrement SSL ajoutent une surcharge à chaque message transmis via une connexion établie.

    Les processeurs modernes gèrent rapidement le chiffrement et le déchiffrement. D'autres facteurs, tels que les E/S disque et l'attente dans les files d'attente, consomment davantage de temps lors d'une requête ; l'impact sur les performances dû au chiffrement reste donc relativement faible.