全部产品
Search
文档中心

ApsaraDB for MongoDB:Pengujian dampak enkripsi SSL pada kinerja instance

更新时间:Jul 06, 2025

Topik ini menjelaskan cara menguji dampak enkripsi SSL pada kinerja instance ApsaraDB for MongoDB.

Lingkungan pengujian

Buat sebuah ECS instance dan instance ApsaraDB for MongoDB. Untuk informasi lebih lanjut, lihat Buat Instance Set Replika dan Buat dan Kelola ECS Instance di Konsol (Versi Ekspres).

Tabel berikut menjelaskan pengaturan untuk ECS instance dan ApsaraDB for MongoDB instance yang digunakan dalam pengujian.

  • ApsaraDB for MongoDB Instance

    • Arsitektur Instance: Instance Set Replika

    • Jumlah Node Primer dan Sekunder: Tiga Node

    • Jumlah Node Baca-Saja: Satu Node

    • Spesifikasi Instance: 1 Core dan 2 GB Memori (General-Purpose)

    • Versi Instance: MongoDB 4.2

  • ECS Instance

    • Tipe Instance: ecs.e-c1m2.large (2 Core dan 4 GB Memori)

Metode pengujian

Impor data uji

Dalam pengujian, Yahoo! Cloud Serving Benchmark (YCSB) digunakan untuk mengimpor 1.000.000 entri ke dalam koleksi bernama usertable di database bernama ycsb. Jalankan perintah berikut untuk mengimpor entri:

./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

Koleksi yang dihasilkan oleh YCSB memiliki struktur berikut:

{
  "_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==\")"
}

Jalankan skrip uji

YCSB tidak mendukung uji stres dengan enkripsi SSL diaktifkan. Oleh karena itu, skrip uji digunakan untuk uji stres dalam topik ini. Skrip tersebut berisi konten berikut.

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"Fungsi {func.__name__} membutuhkan waktu {elapsed_time:.4f} millidetik untuk dieksekusi.")

            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"uji, with_ssl: {with_ssl}, repeat: {repeat}")
    ssl_suffix = "tanpa-ssl"
    if with_ssl:
        ssl_suffix = "dengan-ssl"
    suffix = f"{repeat}-{ssl_suffix}.log"
    only_connection_file = f"hanya-koneksi-{suffix}"
    first_query_file = f"pertama-query-{suffix}"
    connection_and_first_query_file = f"koneksi-dan-pertama-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"uji selesai, tulis ke {only_connection_file}, {first_query_file} dan {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"mulai 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"akhir query, repeat: {repeat}, total: {total} millidetik, rata-rata: {avg} millidetik")


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

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

Selama pengujian, Anda dapat memodifikasi parameter berikut sesuai kebutuhan:

  • client: Ganti string koneksi, nama pengguna, dan kata sandi dalam tanda kurung parameter pymongo.MongoClient() dengan informasi aktual dari ApsaraDB for MongoDB instance.

  • repeat: Jumlah kali pengujian dijalankan. Pengujian dijalankan sebanyak 5.000 kali. Anda dapat memodifikasi parameter ini sesuai kebutuhan.

Skrip mengeluarkan parameter berikut:

  • hanya-koneksi: Mencatat waktu yang dikonsumsi untuk menetapkan koneksi.

  • pertama-query: mencatat durasi query pertama setelah koneksi ditetapkan.

  • koneksi-dan-pertama-query: Mencatat durasi total mulai dari penyetapan koneksi hingga selesainya query pertama. Nilai parameter ini adalah jumlah dari nilai hanya-koneksi dan pertama-query.

  • latensi: Mencatat durasi rata-rata dari 5.000 query ketika klien yang ditentukan oleh pymongo.MongoClient() digunakan kembali.

Hasil pengujian

Tabel berikut menjelaskan nilai rata-rata dari 5.000 pengujian.

Item

Waktu yang dikonsumsi dengan enkripsi SSL dinonaktifkan (ms)

Waktu yang dikonsumsi dengan enkripsi SSL diaktifkan (ms)

Waktu yang dikonsumsi untuk menetapkan koneksi

3,7009

19,8515

Durasi query pertama setelah koneksi ditetapkan

20,7456

43,5884

Total durasi dari penyetapan koneksi hingga selesainya query pertama

24,4465

63,4399

Durasi query rata-rata ketika klien yang ditentukan digunakan kembali

0,7506

0,7643

Setelah pengujian, perbedaan antara durasi dengan enkripsi SSL diaktifkan dan dinonaktifkan terutama terletak pada penyetapan koneksi. Jika koneksi yang ada digunakan kembali, perbedaan kecil terdapat antara durasi query rata-rata dengan enkripsi SSL diaktifkan dan dinonaktifkan. Alasan utama untuk perbedaan durasi kecil ini meliputi dua aspek berikut:

  • Round-Trip Time (RTT) tambahan ada ketika koneksi dibuat antara klien dan server Anda karena penggunaan Transport Layer Security (TLS).

    Jika Anda mengonfigurasi kolam koneksi, overhead RTT tambahan dari penyetapan koneksi tersebar secara merata. Jika Anda menggunakan kembali klien yang ditentukan setelah mengaktifkan fitur enkripsi SSL, TLS RTT dapat diminimalkan selama setiap penyetapan koneksi.

  • Setelah koneksi ditetapkan, overhead tambahan dihasilkan ketika algoritma enkripsi dan dekripsi digunakan oleh badan pesan.

    CPU dapat dengan cepat mengenkripsi dan mendekripsi badan pesan, aspek sistem lainnya mungkin memakan waktu lama dalam query, seperti disk I/O dan antrian menunggu, dan dampak enkripsi dan dekripsi pada kinerja keseluruhan relatif kecil.