Men-deploy Memcached di GKE


Dalam tutorial ini, Anda akan mempelajari cara men-deploy cluster server Memcached di Google Kubernetes Engine (GKE) menggunakan Kubernetes, Helm, dan Mcrouter. Memcached adalah sistem caching open source serbaguna yang populer. Sistem ini biasanya berfungsi sebagai penyimpanan sementara untuk data yang sering digunakan mempercepat aplikasi web dan meringankan muatan database.

Karakteristik Memcached

Memcached memiliki dua sasaran desain utama:

  • Kemudahan: Memcached berfungsi seperti tabel hash besar dan menawarkan API sederhana untuk menyimpan dan mengambil objek berbentuk sembarang menurut kunci.
  • Kecepatan: Memcached menyimpan data cache secara eksklusif di dalam random access memory (RAM), sehingga akses data menjadi sangat cepat.

Memcached adalah sistem terdistribusi yang memungkinkan kapasitas tabel hash-nya untuk diskalakan secara horizontal di seluruh kumpulan server. Setiap server Memcached beroperasi secara terpisah dari server lain dalam kumpulan. Oleh karena itu, perutean dan load balancing antara server harus dilakukan di level klien. Klien Memcached menerapkan skema hashing yang konsisten untuk memilih server target dengan tepat. Skema ini menjamin kondisi berikut:

  • Server yang sama selalu dipilih untuk kunci yang sama.
  • Penggunaan memori diseimbangkan di antara server secara merata.
  • Jumlah minimum kunci yang dipindahkan saat kumpulan server dikurangi atau diperluas.

Diagram berikut menggambarkan interaksi tingkat tinggi antara klien Memcached dan kumpulan server Memcached terdistribusi.

interaksi antara memcached dan kumpulan server memcached
Gambar 1: Interaksi tingkat tinggi antara klien Memcached dan kumpulan server Memcached terdistribusi.

Tujuan

  • Mempelajari beberapa karakteristik arsitektur terdistribusi Memcached.
  • Men-deploy layanan Memcached ke GKE menggunakan Kubernetes dan Helm.
  • Men-deploy Mcrouter, proxy Memcached open source, untuk meningkatkan performa sistem.

Biaya

Dalam dokumen ini, Anda akan menggunakan komponen Google Cloud yang dapat ditagih berikut:

  • Compute Engine

Untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda, gunakan kalkulator harga. Pengguna baru Google Cloud mungkin memenuhi syarat untuk mendapatkan uji coba gratis.

Sebelum memulai

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the Compute Engine and GKE APIs.

    Enable the APIs

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Enable the Compute Engine and GKE APIs.

    Enable the APIs

  8. Mulai instance Cloud Shell.
    Buka Cloud Shell

Men-deploy layanan Memcached

Salah satu cara sederhana untuk men-deploy layanan Memcached ke GKE adalah dengan menggunakan chart Helm. Untuk melanjutkan deployment, ikuti langkah-langkah berikut di Cloud Shell:

  1. Buat cluster GKE baru yang terdiri dari tiga node:

    gcloud container clusters create demo-cluster --num-nodes 3 --zone us-central1-f
    
  2. Download arsip biner helm:

    HELM_VERSION=3.7.1
    cd ~
    wget https://get.helm.sh/helm-v${HELM_VERSION}-linux-amd64.tar.gz
    
  3. Ekstrak file zip arsip ke sistem lokal Anda:

    mkdir helm-v${HELM_VERSION}
    tar zxfv helm-v${HELM_VERSION}-linux-amd64.tar.gz -C helm-v${HELM_VERSION}
    
  4. Tambahkan direktori biner helm ke variabel lingkungan PATH Anda:

    export PATH="$(echo ~)/helm-v${HELM_VERSION}/linux-amd64:$PATH"
    

    Perintah ini membuat biner helm dapat ditemukan dari direktori mana pun selama sesi Cloud Shell saat ini. Agar konfigurasi ini tetap ada di beberapa sesi, tambahkan perintah ke file ~/.bashrc pengguna Cloud Shell Anda.

  5. Instal rilis chart Helm Memcached baru dengan arsitektur ketersediaan tinggi:

    helm repo add bitnami https://charts.bitnami.com/bitnami
    helm install mycache bitnami/memcached --set architecture="high-availability" --set autoscaling.enabled="true"
    

    Chart Helm Memcached menggunakan pengontrol StatefulSet. Salah satu manfaat menggunakan pengontrol StatefulSet adalah nama pod menjadi teratur dan dapat diprediksi. Dalam hal ini, namanya adalah mycache-memcached-{0..2}. Pengurutan ini mempermudah klien Memcached untuk mereferensikan server.

  6. Untuk melihat pod yang berjalan, jalankan perintah berikut:

    kubectl get pods
    

    Output konsol Google Cloud akan tampak seperti berikut:

    NAME                  READY     STATUS    RESTARTS   AGE
    mycache-memcached-0   1/1       Running   0          45s
    mycache-memcached-1   1/1       Running   0          35s
    mycache-memcached-2   1/1       Running   0          25s

Menemukan endpoint layanan Memcached

Chart Helm Memcached menggunakan layanan headless. Layanan headless mengekspos alamat IP untuk semua podnya sehingga dapat ditemukan satu per satu.

  1. Pastikan layanan yang di-deploy headless:

    kubectl get service mycache-memcached -o jsonpath="{.spec.clusterIP}"
    

    Output None mengonfirmasi bahwa layanan tidak memiliki clusterIP dan oleh karena itu bersifat headless.

    Layanan membuat data DNS untuk nama host formulir:

    [SERVICE_NAME].[NAMESPACE].svc.cluster.local
    

    Dalam tutorial ini, nama layanannya adalah mycache-memcached. Karena tidak ditentukan secara eksplisit, namespace default akan digunakan, sehingga seluruh nama host adalah mycache-memcached.default.svc.cluster.local. Nama host ini me-resolve ke serangkaian alamat IP dan domain untuk ketiga pod yang diekspos oleh layanan. Jika di kemudian hari beberapa pod ditambahkan ke kumpulan atau pod lama dihapus, kube-dns akan otomatis memperbarui data DNS.

    Klien bertanggung jawab untuk menemukan endpoint layanan Memcached, seperti yang dijelaskan pada langkah berikutnya.

  2. Ambil alamat IP endpoint:

    kubectl get endpoints mycache-memcached
    

    Outputnya mirip dengan berikut ini:

    NAME                ENDPOINTS                                            AGE
    mycache-memcached   10.36.0.32:11211,10.36.0.33:11211,10.36.1.25:11211   3m
    

    Perhatikan bahwa setiap pod Memcached memiliki alamat IP terpisah, masing-masing 10.36.0.32, 10.36.0.33, dan 10.36.1.25. Alamat IP ini mungkin berbeda untuk instance server Anda sendiri. Setiap pod memproses port 11211, yang merupakan port default Memcached.

  3. Untuk alternatif langkah 2, lakukan pemeriksaan DNS dengan menggunakan bahasa pemrograman seperti Python:

    1. Mulai konsol interaktif Python di dalam cluster Anda:

      kubectl run -it --rm python --image=python:3.10-alpine --restart=Never python
      
    2. Di konsol Python, jalankan perintah berikut:

      import socket
      print(socket.gethostbyname_ex('mycache-memcached.default.svc.cluster.local'))
      exit()
      

      Outputnya mirip dengan berikut ini:

      ('mycache-memcached.default.svc.cluster.local', ['mycache-memcached.default.svc.cluster.local'], ['10.36.0.32', '10.36.0.33', '10.36.1.25'])
  4. Uji deployment dengan membuka sesi telnet menggunakan salah satu server Memcached yang berjalan pada port 11211:

    kubectl run -it --rm busybox --image=busybox:1.33 --restart=Never telnet mycache-memcached-0.mycache-memcached.default.svc.cluster.local 11211
    

    Pada prompt telnet, jalankan perintah ini menggunakan protokol ASCII Memcached:

    set mykey 0 0 5
    hello
    get mykey
    quit

    Output yang dihasilkan ditampilkan di sini dengan huruf tebal:

    set mykey 0 0 5
    hello
    STORED
    get mykey
    VALUE mykey 0 5
    hello
    END
    quit

Mengimplementasikan logika penemuan layanan

Sekarang Anda siap mengimplementasikan logika penemuan layanan dasar yang ditunjukkan dalam diagram berikut.

<img <="" alt="service discovery logic" img="" src="/static/architecture/images/memcached-fig-2.svg" />
Gambar 2: Logika penemuan layanan.

Pada tingkat tinggi, logika penemuan layanan terdiri dari langkah-langkah berikut:

  1. Aplikasi membuat kueri kube-dns untuk data DNS mycache-memcached.default.svc.cluster.local.
  2. Aplikasi mengambil alamat IP yang terkait dengan data tersebut.
  3. Aplikasi membuat instance klien Memcached baru dan memberikannya bersama alamat IP yang diambil.
  4. Load balancer terintegrasi milik klien Memcached terhubung ke server Memcached di alamat IP yang ditentukan.

Sekarang Anda menerapkan logika penemuan layanan ini menggunakan Python:

  1. Deploy pod baru berkemampuan Python di cluster Anda dan mulai sesi shell di dalam pod:

    kubectl run -it --rm python --image=python:3.10-alpine --restart=Never sh
    
  2. Instal pymemcache library:

    pip install pymemcache
    
  3. Mulai konsol interaktif Python dengan menjalankan perintah python.

  4. Di konsol Python, jalankan perintah berikut:

    import socket
    from pymemcache.client.hash import HashClient
    _, _, ips = socket.gethostbyname_ex('mycache-memcached.default.svc.cluster.local')
    servers = [(ip, 11211) for ip in ips]
    client = HashClient(servers, use_pooling=True)
    client.set('mykey', 'hello')
    client.get('mykey')
    

    Outputnya adalah sebagai berikut:

    b'hello'

    Awalan b menandakan literal byte, yang merupakan format tempat Memcached menyimpan data.

  5. Keluar dari konsol Python:

    exit()
    
  6. Untuk keluar dari sesi shell pod, tekan Control+D.

Mengaktifkan penggabungan koneksi

Seiring dengan meningkatnya kebutuhan caching Anda dan skala kumpulan hingga puluhan, ratusan, atau ribuan server Memcached, Anda mungkin menemui beberapa batasan. Secara khusus, sejumlah besar koneksi terbuka dari klien Memcached mungkin menempatkan beban berat pada server, seperti yang ditunjukkan pada diagram berikut.

<img <="" alt="High number of open connections when all Memcached clients access all Memcached servers directly" img="" src="/static/architecture/images/memcached-fig-3.svg" />
Gambar 3: Jumlah koneksi terbuka yang tinggi saat semua klien Memcached mengakses semua server Memcached secara langsung.

Untuk mengurangi jumlah koneksi terbuka, Anda harus membuat proxy untuk mengaktifkan penggabungan koneksi, seperti dalam diagram berikut.

<img <="" alt="Proxy untuk mengaktifkan penggabungan koneksi." img="" src="/static/architecture/images/memcached-fig-4.svg" />
Gambar 4: Menggunakan proxy untuk mengurangi jumlah koneksi terbuka.

Mcrouter (diucapkan "mick router"), proxy Memcached open source yang canggih, memungkinkan penggabungan koneksi. Integrasi Mcrouter berjalan lancar, karena menggunakan protokol ASCII Memcached standar. Untuk klien Memcached, Mcrouter berperilaku seperti server Memcached normal. Untuk server Memcached, Mcrouter berperilaku seperti klien Memcached normal.

Untuk men-deploy Mcrouter, jalankan perintah berikut di Cloud Shell.

  1. Hapus rilis chart Helm mycache yang diinstal sebelumnya:

    helm delete mycache
    
  2. Deploy pod Memcached dan pod Mcrouter baru dengan menginstal rilis chart Helm Mcrouter baru:

    helm repo add stable https://charts.helm.sh/stable
    helm install mycache stable/mcrouter --set memcached.replicaCount=3
    

    Pod proxy kini siap menerima permintaan dari aplikasi klien.

  3. Uji penyiapan ini dengan menghubungkan ke salah satu pod proxy. Gunakan perintah telnet pada port 5000, yang merupakan port default Mcrouter.

    MCROUTER_POD_IP=$(kubectl get pods -l app=mycache-mcrouter -o jsonpath="{.items[0].status.podIP}")
    
    kubectl run -it --rm busybox --image=busybox:1.33 --restart=Never telnet $MCROUTER_POD_IP 5000
    

    Pada prompt telnet, jalankan perintah berikut:

    set anotherkey 0 0 15
    Mcrouter is fun
    get anotherkey
    quit

    Perintah mengatur dan mencerminkan nilai kunci Anda.

Sekarang Anda telah men-deploy proxy yang memungkinkan penggabungan koneksi.

Mengurangi latensi

Untuk meningkatkan ketahanan, praktik yang umum digunakan adalah menggunakan cluster dengan beberapa node. Tutorial ini menggunakan cluster dengan tiga node. Namun, penggunaan beberapa node juga berisiko meningkatkan latensi yang disebabkan oleh traffic jaringan antar-node yang lebih berat.

Menentukan lokasi pod proxy

Anda dapat mengurangi risiko ini dengan menghubungkan pod aplikasi klien hanya ke pod proxy Memcached yang berada di node yang sama. Diagram berikut mengilustrasikan konfigurasi ini.

<img <="" alt="topology for interactions between pods" img="" src="/static/architecture/images/memcached-fig-5.svg" />
Gambar 5: Topologi untuk interaksi antara pod aplikasi, pod Mcrouter, dan pod Memcached di cluster berisi tiga node.

Jalankan konfigurasi ini seperti berikut:

  1. Pastikan setiap node berisi satu pod proxy yang berjalan. Pendekatan umumnya adalah men-deploy pod proxy dengan pengontrol DaemonSet. Saat node ditambahkan ke cluster, pod proxy baru akan otomatis ditambahkan ke dalamnya. Saat node dihapus dari cluster, pod tersebut akan dibersihkan dari sampah memori. Dalam tutorial ini, chart Helm Mcrouter yang Anda deploy sebelumnya menggunakan pengontrol DaemonSet secara default. Jadi, langkah ini sudah selesai.
  2. Tetapkan nilai hostPort di parameter Kubernetes container proxy agar node memproses port tersebut dan mengalihkan traffic ke proxy. Dalam tutorial ini, chart Helm Mcrouter menggunakan parameter ini secara default untuk port 5000. Jadi langkah ini juga sudah selesai.
  3. Ekspos nama node sebagai variabel lingkungan di dalam pod aplikasi menggunakan entri spec.env dan memilih nilai spec.nodeName fieldRef. Pelajari metode ini lebih lanjut di dokumentasi Kubernetes.

    1. Men-deploy Pod aplikasi contoh. Perintah berikut menerapkan Deployment Kubernetes. Deployment adalah objek Kubernetes API yang memungkinkan Anda menjalankan beberapa replika Pod yang didistribusikan di antara node dalam cluster:

      cat <<EOF | kubectl create -f -
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: sample-application
      spec:
        selector:
          matchLabels:
            app: sample-application
        replicas: 9
        template:
          metadata:
            labels:
              app: sample-application
          spec:
            containers:
              - name: busybox
                image: busybox:1.33
                command: [ "sh", "-c"]
                args:
                - while true; do sleep 10; done;
                env:
                  - name: NODE_NAME
                    valueFrom:
                      fieldRef:
                        fieldPath: spec.nodeName
      EOF
      
  4. Pastikan nama node terlihat, dengan melihat ke dalam salah satu contoh pod aplikasi:

    POD=$(kubectl get pods -l app=sample-application -o jsonpath="{.items[0].metadata.name}")
    
    kubectl exec -it $POD -- sh -c 'echo $NODE_NAME'
    

    Perintah ini menghasilkan nama node dalam bentuk berikut:

    gke-demo-cluster-default-pool-XXXXXXXX-XXXX

Menghubungkan pod

Contoh pod aplikasi kini siap terhubung ke pod Mcrouter yang berjalan pada masing-masing node bersama di port 5000, yang merupakan port default Mcrouter.

  1. Mulai koneksi untuk salah satu pod dengan membuka sesi telnet:

    POD=$(kubectl get pods -l app=sample-application -o jsonpath="{.items[0].metadata.name}")
    
    kubectl exec -it $POD -- sh -c 'telnet $NODE_NAME 5000'
    
  2. Pada prompt telnet, jalankan perintah berikut:

    get anotherkey
    quit
    

    Hasil output:

    Mcrouter is fun

Terakhir, sebagai ilustrasi, kode Python berikut adalah contoh program yang melakukan koneksi ini dengan mengambil variabel NODE_NAME dari lingkungan dan menggunakan library pymemcache:

import os
from pymemcache.client.base import Client

NODE_NAME = os.environ['NODE_NAME']
client = Client((NODE_NAME, 5000))
client.set('some_key', 'some_value')
result = client.get('some_key')

Pembersihan

Agar tidak perlu membayar biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam tutorial ini, hapus project yang berisi resource tersebut, atau simpan project dan hapus setiap resource.

  1. Jalankan perintah berikut untuk menghapus cluster GKE:

    gcloud container clusters delete demo-cluster --zone us-central1-f
    
  2. Jika ingin, hapus biner Helm:

    cd ~
    rm -rf helm-v3.7.1
    rm helm-v3.7.1-linux-amd64.tar.gz
    

Langkah selanjutnya

  • Pelajari berbagai fitur lain yang ditawarkan Mcrouter di luar penggabungan koneksi sederhana, seperti replika failover, streaming penghapusan yang andal, warmup cache cold, siaran multi-cluster.
  • Pelajari file sumber chart Memcached dan chart Mcrouter untuk mengetahui detail selengkapnya tentang masing-masing konfigurasi Kubernetes.
  • Baca tentang teknik efektif untuk menggunakan Memcached di App Engine. Beberapa di antaranya berlaku untuk platform lain, seperti GKE.