Lewati ke konten utama
Superscaler, Autoscaler Open-Source untuk Supervisor Workers
  1. Semua Artikel/

Superscaler, Autoscaler Open-Source untuk Supervisor Workers

 Author
Penulis
Hasbi Mizan Azzami
DevOps Enthusiast

Superscaler adalah service untuk melakukan autoscaling terhadap worker Supervisor. Service ini dirancang untuk menambah atau mengurangi jumlah proses worker di Supervisor secara otomatis sesuai dengan beban kerja yang masuk.

Supervisor secara bawaan tidak mendukung fitur autoscaling. Namun, Supervisor menyebutkan di dokumentasinya bahwa mereka menyediakan RPC interface yang fungsionalitasnya dapat diperluas.

Supervisor's XML-RPC interface may be extended arbitrarily by programmers. 
Additional top-level namespace XML-RPC interfaces can be added
using the [rpcinterface:foo] declaration in the configuration file.

Superscaler memanfaatkan celah ini untuk memanipulasi in-memory process dictionary milik Supervisor melalui custom plugin. Hasilnya, Superscaler bisa menambah atau mengurangi jumlah worker tanpa perlu me-restart worker lain yang sedang memproses queue. Selain itu, Superscaler juga mendukung beberapa queue backend secara bersamaan. Setiap target bisa memonitor sistem queue yang berbeda. Backend yang didukung saat ini adalah RabbitMQ (via AMQP) dan Redis (via list length).

Superscaler terdiri dari dua komponen:

  1. Main Daemon (superscaler)
  2. Supervisor RPC Plugin (superscaler_plugin)

Algoritma Scaling
#

Untuk setiap target yang dikonfigurasi, daemon Superscaler secara berkala melakukan pengecekan berdasarkan konfigurasi poll_interval.

  1. Superscaler mengambil queue depth dari backend yang dikonfigurasi dan menghitung: desired_workers = ceil(queue_len / tasks_per_worker).
  2. Membatasi desired_workers di antara min_workers dan max_workers.
  3. Mengecek jumlah worker aktif yang sedang berjalan di Supervisor.
  4. Jika active < desired: mengirim RPC call scaleUp (maksimal sebanyak scale_up_step) dengan syarat waktu cooldown_up sudah terlewati dan tidak ada proses yang sedang dalam tahap di-stop.
  5. Jika active > desired: mengirim RPC call scaleDown (maksimal sebanyak scale_down_step) dengan syarat waktu cooldown_down sudah terlewati dan tidak ada proses yang sedang dalam tahap di-stop.

Cara Kerja
#

Supervisor standar tidak mendukung penambahan atau penghapusan proses secara dinamis tanpa melakukan reload yang bersifat disruptif. Maka dari itu, Superscaler menyediakan custom XML-RPC plugin ([rpcinterface:superscaler]) untuk mengatasi keterbatasan tersebut.

Scaling Up
#

Plugin secara dinamis menaikkan nilai numprocs di dalam file konfigurasi .ini pada disk, kemudian melakukan re-parse secara internal menggunakan parser bawaan Supervisor, dan langsung membuat objek worker baru ke dalam live supervisor memory dictionary. Secara spesifik, RPC plugin membandingkan konfigurasi group yang baru di-parse dengan in-memory process directory yang sedang berjalan. Untuk setiap nama proses baru yang ditemukan (misalnya worker_03), plugin membuat objek Process internal menggunakan make_process() milik Supervisor, menambahkannya ke dict group.processes, dan mengandalkan transisi main loop Supervisor berikutnya untuk secara natural (auto_spawn) memulai proses tersebut ke state STARTING.

Scaling Down
#

Untuk menghindari kill paksa terhadap job yang sedang berjalan, scaleDown hanya mengirim sinyal graceful stop ke proses dengan nomor tertinggi terlebih dahulu. Daemon secara berkala mengecek state dari worker yang sedang di-stop melalui polling. Hanya ketika state mereka berhasil bertransisi ke STOPPED_STATES, daemon baru mengirim confirmScaleDown. Pada fase konfirmasi ini, plugin menulis ulang file konfigurasi pada disk untuk secara resmi menurunkan numprocs, melakukan re-parse, dan akhirnya menghapus instance Process yang sudah di-stop dari dict group.processes. Urutan operasi yang presisi ini mencegah terjadinya divergensi fatal antara in-memory state dan file konfigurasi jika sistem crash di tengah proses.

Clustering
#

Superscaler mendukung arsitektur clustering master/slave untuk mengelola worker Supervisor di beberapa server sekaligus.

Master node menjalankan daemon Superscaler (superscaler). Master membaca konfigurasi, melakukan polling terhadap queue, dan mengirimkan perintah scaling ke semua node yang dikonfigurasi. Sedangkan slave node hanya menjalankan Supervisor dengan superscaler_plugin terpasang. Slave mengekspos HTTP XML-RPC endpoint supaya master bisa menjangkaunya secara remote. Slave node tidak perlu menjalankan daemon Superscaler.

Untuk node lokal (di mesin yang sama dengan daemon), Superscaler berkomunikasi melalui Unix socket. Untuk node remote, Superscaler menggunakan HTTP XML-RPC standar (xmlrpc.client.ServerProxy) dengan opsional HTTP Basic Auth.

Konfigurasi Node
#

Setiap node didefinisikan dengan section [node:<name>] di dalam superscaler.conf. Nama yang digunakan adalah identifier unik yang bisa dipilih sendiri (misalnya local, worker-1).

ParameterDeskripsi
urlWajib. Endpoint URL. Gunakan http://host:port/RPC2 untuk remote node atau unix:///path/to/socket untuk local node.
usernameUsername Supervisor untuk autentikasi. Kosongkan jika tidak ada.
passwordPassword Supervisor untuk autentikasi. Kosongkan jika tidak ada.

Contoh konfigurasi node:

[node:local]
url = unix:///var/run/supervisor.sock
username =
password =

[node:worker-1]
url = http://192.168.1.10:9001/RPC2
username = admin
password = secret

[node:worker-2]
url = http://192.168.1.11:9001/RPC2
username = admin
password = secret

Parameter nodes pada Target
#

Setiap section [target:*] menerima parameter nodes berupa daftar nama [node:<name>] yang dipisahkan koma. Parameter ini menentukan node mana saja yang akan di-scale oleh target tersebut.

[target:main-scaler]
type = supervisor
queue = main-rabbit
queue_key = tasks
program_name = example-worker
nodes = local, worker-1, worker-2
tasks_per_worker = 50
min_workers = 2
max_workers = 30

Ketika scaling up, worker ditambahkan ke node yang memiliki worker aktif paling sedikit (least-loaded). Ketika scaling down, worker dihapus dari node yang memiliki worker aktif paling banyak (most-loaded).

Jika tidak ada section [node:*] yang didefinisikan tapi section [supervisor] ada, Superscaler secara otomatis membuat default node dari konfigurasi [supervisor]. Konfigurasi lama tetap berjalan tanpa perubahan.

Prasyarat
#

KomponenVersi Minimum
Python3.9
redis-py4.0.0
pika1.2.0

Superscaler menyediakan package instalasi standar untuk distribusi .rpm dan .deb.

Instalasi
#

Red Hat / CentOS
#

  1. Download package RPM
curl -LO https://github.com/mijonOfTheMoon/superscaler/releases/download/3.0.0/superscaler-3.0.0-1.amzn2023.noarch.rpm
  1. Instal package
sudo dnf install superscaler-3.0.0-1.amzn2023.noarch.rpm

Debian / Ubuntu
#

  1. Download package DEB
curl -LO https://github.com/mijonOfTheMoon/superscaler/releases/download/3.0.0/superscaler_3.0.0-1_all.deb
  1. Instal package
sudo dpkg -i superscaler_3.0.0-1_all.deb

Service Superscaler tidak diaktifkan atau dijalankan secara otomatis setelah instalasi. Hal ini disengaja karena slave node hanya membutuhkan plugin, bukan daemon.

Setup Master Node
#

Master node menjalankan daemon Superscaler dan mengkoordinasikan scaling ke semua node.

  1. Instal package (RPM atau DEB seperti di atas).

  2. Konfigurasi /etc/superscaler/superscaler.conf dengan section [node:<name>] untuk setiap node Supervisor di dalam cluster:

[node:local]
url = unix:///var/run/supervisor.sock
username =
password =

[node:worker-1]
url = http://192.168.1.10:9001/RPC2
username = admin
password = secret
  1. Definisikan target dengan parameter nodes yang merujuk ke node yang sudah dikonfigurasi:
[target:main-scaler]
type = supervisor
queue = main-rabbit
queue_key = tasks
program_name = example-worker
nodes = local, worker-1
tasks_per_worker = 50
min_workers = 2
max_workers = 20
  1. Aktifkan dan jalankan service Superscaler:
sudo systemctl enable superscaler
sudo systemctl start superscaler
  1. Jika master node juga menjalankan worker Supervisor, tambahkan plugin ke supervisord.conf lokal:
[rpcinterface:superscaler]
supervisor.rpcinterface_factory = superscaler_plugin.rpcinterface:SuperscalerNamespaceRPCInterface

Kemudian restart Supervisor:

sudo systemctl restart supervisor

Setup Slave Node
#

Slave node menjalankan Supervisor dengan plugin dan mengekspos HTTP XML-RPC endpoint. Daemon Superscaler tidak perlu berjalan di slave node.

  1. Instal package (RPM atau DEB seperti di atas). Service tetap disabled secara default.

  2. Tambahkan plugin [rpcinterface:superscaler] ke /etc/supervisor/supervisord.conf:

[rpcinterface:superscaler]
supervisor.rpcinterface_factory = superscaler_plugin.rpcinterface:SuperscalerNamespaceRPCInterface
  1. Aktifkan section [inet_http_server] di /etc/supervisor/supervisord.conf supaya master bisa menjangkau node ini melalui HTTP:
[inet_http_server]
port = 0.0.0.0:9001
username = admin
password = secret

Gunakan password yang kuat dan batasi akses jaringan (firewall rules, private network) untuk mengamankan endpoint.

  1. Restart Supervisor untuk mengapply perubahan:
sudo systemctl restart supervisor

Cukup itu saja untuk slave. Tidak perlu mengaktifkan atau menjalankan service Superscaler karena semua keputusan scaling ditangani oleh master node secara remote.

Konfigurasi
#

Tambahkan plugin berikut ke dalam konfigurasi supervisord.conf:

[rpcinterface:superscaler]
supervisor.rpcinterface_factory = superscaler_plugin.rpcinterface:SuperscalerNamespaceRPCInterface

Setelah menambahkan plugin, konfigurasi Superscaler bisa dilakukan. Path default untuk file konfigurasi Superscaler adalah /etc/superscaler/superscaler.conf.

Section [supervisor]
#

Mengkonfigurasi communication layer ke daemon Supervisor.

ParameterDeskripsi
unix_socket_pathUNIX socket URI untuk XML-RPC (contoh: unix:///var/run/supervisor.sock)
usernameUsername Supervisor. Kosongkan jika tidak ada.
passwordPassword Supervisor. Kosongkan jika tidak ada.

Section [queue:<name>]
#

Mendefinisikan queue backend. Beberapa backend dapat dikonfigurasi secara bersamaan. Parameter type menentukan backend driver yang digunakan.

ParameterDeskripsi
typeWajib. Tipe backend: rabbitmq atau redis

Parameter RabbitMQ (type = rabbitmq):

ParameterDeskripsi
hostHostname server RabbitMQ (contoh: 127.0.0.1)
portPort AMQP (contoh: 5672)
usernameUsername RabbitMQ (contoh: guest)
passwordPassword RabbitMQ (contoh: guest)
vhostVirtual host (contoh: /)

Parameter Redis (type = redis):

ParameterDeskripsi
hostIP atau hostname server Redis (contoh: 127.0.0.1)
portPort Redis (contoh: 6379)
passwordPassword Redis. Kosongkan jika tidak ada.
dbIndex integer Redis DB (contoh: 0)

Section [target:<nama_target>]
#

Setiap target worker pool harus didefinisikan dengan prefix [target:<nama_target>]. Misalnya, [target:example-scaler].

ParameterDeskripsi
queueWajib. Nama section [queue:*] yang digunakan sebagai queue backend.
queue_keyWajib. Key atau nama queue yang dimonitor di backend.
program_nameWajib. Nama program Supervisor yang akan di-autoscale.
tasks_per_workerWajib. Rasio pending tasks yang diharapkan untuk setiap worker.
min_workersWajib. Batas minimum jumlah proses worker.
max_workersWajib. Batas maksimum jumlah proses worker.
poll_intervalOpsional. Durasi dalam detik antar pengecekan queue. Default 10.
scale_up_stepOpsional. Batas jumlah worker yang ditambahkan per aksi scale up. Default 1.
scale_down_stepOpsional. Batas jumlah worker yang dihapus per aksi scale down. Default 1.
cooldown_upOpsional. Durasi aman dalam detik sebelum mengizinkan scale up berikutnya. Default 0.
cooldown_downOpsional. Durasi aman dalam detik sebelum mengizinkan scale down berikutnya. Default 0.
nodesOpsional. Daftar nama [node:<name>] yang dipisahkan koma untuk multi-node scaling.

Post Konfigurasi
#

Untuk setup single-node menggunakan section [supervisor], restart kedua service:

sudo systemctl restart supervisor
sudo systemctl restart superscaler

Untuk setup multi-node cluster, ikuti panduan Setup Master Node dan Setup Slave Node di atas.