- Knight Capital Group, salah satu pilar besar perdagangan saham AS, terdorong ke ambang kebangkrutan akibat kegagalan deployment SMARS pada 1 Agustus 2012, yang menyebabkan kerugian 460 juta dolar hanya dalam 45 menit
- Dalam proses merespons Retail Liquidity Program NYSE, penggunaan ulang flag dari kode Power Peg yang sudah tidak dipakai selama 8 tahun untuk fitur baru menjadi titik awal insiden
- Kode baru hanya dideploy ke 7 dari 8 server, dan ketika satu server yang tersisa menerima order RLP baru, fungsi Power Peg yang sudah “mati” berjalan kembali
- Power Peg terus merutekan child order tanpa melacak volume eksekusi parent order, dan Knight harus mencari penyebabnya di lingkungan produksi tanpa kill switch maupun prosedur respons yang terdokumentasi
- Deployment sama pentingnya dengan penulisan dan pengujian kode, dan deployment yang bergantung pada prosedur manual menjadi risiko operasional yang fatal tanpa otomatisasi, repeatability, dan verifikasi
Perusahaan high-frequency trading yang runtuh dalam 45 menit
- Knight Capital Group adalah perusahaan jasa keuangan AS yang bergerak di market making, eksekusi elektronik, serta penjualan dan trading institusional
- Pada 2012, Knight adalah trader terbesar di saham AS dengan sekitar 17% pangsa pasar masing-masing di NYSE dan NASDAQ
- Electronic Trading Group (ETG) milik Knight mengelola volume rata-rata lebih dari 3,3 miliar transaksi per hari, dan memperdagangkan lebih dari 21 miliar dolar per hari
- Pada 31 Juli 2012, Knight memiliki sekitar 365 juta dolar dalam kas dan setara kas
Pembaruan SMARS untuk merespons RLP
- NYSE dijadwalkan memulai Retail Liquidity Program pada 1 Agustus 2012
- Knight memperbarui SMARS, router algoritmik otomatis berkecepatan tinggi yang mengirim order ke pasar, untuk menyesuaikan diri dengan hal ini
- SMARS adalah sistem yang menerima “parent order” dari platform trading dan mengeksekusinya dengan membaginya menjadi satu atau lebih “child order”
- Semakin besar parent order, semakin banyak child order yang dibuat
- Pembaruan kali ini dimaksudkan untuk menggantikan kode Power Peg yang sudah tidak digunakan selama 8 tahun
- Kode baru menggunakan ulang flag lama yang sebelumnya mengaktifkan Power Peg untuk fungsi baru
- Kode itu sendiri telah diuji dengan cukup dan dipastikan bekerja normal
Satu server yang tertinggal dalam deployment manual
- Dari 27 Juli hingga 31 Juli 2012, Knight mendeploy secara manual software baru ke sejumlah server terbatas per hari, dengan total target 8 server
- Menurut dokumen SEC, seorang teknisi tidak menyalin kode baru ke satu dari 8 server SMARS
- Tidak ada prosedur agar teknisi kedua meninjau deployment ini, dan juga tidak ada prosedur terdokumentasi yang mewajibkan peninjauan semacam itu
- Akibatnya, di server ke-8, kode Power Peg tidak dihapus dan kode RLP baru juga tidak ditambahkan
Cara kode mati hidup kembali
- Pada 1 Agustus 2012 pukul 9:30 pagi (waktu Timur AS), saat pasar dibuka, Knight mulai memproses order pelanggan broker-dealer untuk Retail Liquidity Program
- Tujuh server yang dideploy dengan benar memproses order secara normal
- Order yang masuk ke server ke-8 menjalankan kembali kode Power Peg lama melalui flag yang digunakan ulang
- Power Peg awalnya dirancang untuk menghitung jumlah saham yang dibeli atau dijual relatif terhadap parent order saat child order dieksekusi, lalu menghentikan perutean child order ketika parent order terpenuhi
- Pada 2005, Knight memindahkan fungsi pelacakan kumulatif ke tahap yang lebih awal dalam eksekusi kode, sehingga pelacakan agregat di dalam Power Peg sudah dihapus
- Ketika flag Power Peg aktif di server ke-8, Power Peg merutekan child order ke pasar eksekusi tetapi tidak melacak jumlah saham relatif terhadap parent order, sehingga pada dasarnya berperilaku seperti perulangan tanpa akhir
Sinyal sebelum pembukaan dan ledakan setelah 9:30
- Sistem Knight mulai mengirim email otomatis sejak pukul 8:01 pagi hari itu
- Ini terjadi ketika SMARS memproses order yang ditujukan untuk perdagangan pra-pasar
- Email tersebut menyebut SMARS dan mengidentifikasi error sebagai “Power Peg disabled”
- Dari 8:01 hingga 9:30, 97 email semacam ini dikirim ke karyawan Knight
- Email ini tidak dirancang sebagai alarm sistem sehingga tidak langsung diperiksa
- Tepat setelah pasar dibuka pada 9:30, banyak orang di Wall Street mulai menyadari ada situasi yang tidak normal
- Pada 9:31, sudah jelas sesuatu yang serius sedang terjadi, dan pada 9:32, pertanyaan mengapa hal itu tidak berhenti semakin besar
- Dalam 45 menit pertama, eksekusi Knight menyumbang lebih dari 50% volume perdagangan pada beberapa saham, dan mendorong harga saham tertentu naik lebih dari 10%
- Sebagai reaksi atas transaksi yang salah itu, saham lain justru turun nilainya
Tidak adanya kill switch dan respons yang keliru
- Knight tidak memiliki kill switch untuk segera menghentikan sistem yang bermasalah
- Juga tidak ada prosedur respons yang terdokumentasi, sehingga penyebabnya harus didiagnosis di lingkungan produksi yang memperdagangkan 8 juta saham per menit
- Karena tidak berhasil menemukan penyebabnya, Knight menghapus kode baru dari server yang sebenarnya sudah dideploy dengan benar
- Langkah ini mengakibatkan kode yang bekerja justru dihapus, sementara kode bermasalah tetap dibiarkan
- Setelah itu, parent order tambahan mengaktifkan kode Power Peg bukan hanya di satu server, melainkan di semua server, sehingga masalah makin besar
- Knight baru bisa menghentikan sistem setelah 45 menit berlalu
Skala kerugian dan akhir perusahaan
- Dalam 45 menit pertama setelah pasar dibuka, kode Power Peg menerima dan memproses 212 parent order
- SMARS mengirim jutaan child order ke pasar, yang pada akhirnya menghasilkan 4 juta transaksi di 154 saham dan perdagangan lebih dari 397 juta lembar saham
- Knight menanggung posisi net buy sekitar 3,5 miliar dolar di 80 saham, dan posisi net sell sekitar 3,15 miliar dolar di 74 saham
- Knight Capital Group merealisasikan kerugian 460 juta dolar hanya dalam 45 menit
- Karena saat itu kas dan setara kas yang dimiliki hanya 365 juta dolar, Knight jatuh dari trader saham terbesar AS dan market maker utama menjadi perusahaan yang secara efektif bangkrut
- Untuk menutup kerugian tersebut, perusahaan harus menggalang modal dalam 48 jam, dan Knight berhasil mendapatkan investasi 400 juta dolar dari sekitar 6 investor
- Setelah itu, Knight Capital Group diakuisisi oleh Getco LLC pada Desember 2012, dan perusahaan hasil merger menjadi KCG Holdings
Pelajaran DevOps dan Continuous Delivery
- Membuat dan menguji software yang baik saja tidak cukup
- Untuk mengirimkan nilai kepada pelanggan, software harus dideploy dengan tepat ke pasar
- Penyebab insiden ini bukan hanya satu engineer yang mendeploy SMARS, tetapi juga karena proses Knight tidak mampu menanggung risiko yang terekspos
- Deployment yang bergantung pada orang membaca dan mengikuti instruksi selalu mengandung kemungkinan error
- Kesalahan bisa muncul dari instruksi itu sendiri, cara instruksi ditafsirkan, atau proses pelaksanaannya
- Deployment harus sebisa mungkin diotomatisasi dan repeatable, agar kemungkinan human error berkurang
- Jika sistem deployment otomatis mencakup otomatisasi konfigurasi, deployment, dan pengujian, error yang memicu Knightmare bisa jadi dapat dihindari
- Dari prinsip Continuous Delivery, ada dua prinsip yang relevan untuk kasus ini
- Rilis software harus menjadi proses yang repeatable dan andal
- Otomatiskan sebanyak mungkin dalam batas yang masuk akal
1 komentar
Komentar Hacker News
Saya tidak begitu yakin bagaimana deployment otomatis akan menyelesaikan masalah ini. Justru kemungkinan besar malah memperbesar dampak dan efek ikutannya
Mengubah “developer lupa mengunggah kode ke satu server” menjadi “agen deployment mengalami error saat mengunduh binary/kode baru ke server, dan error itu tidak terlihat karena bug pada agen” tetap menghasilkan mode kegagalan yang sama. Dampaknya mungkin akan menyebar lebih cepat
Tanggung jawab di sini ada pada developer. Karena mereka menulis kode dengan cara yang tidak kompatibel ke belakang
Pasar maupun Knight tahu ada masalah serius, tetapi mereka mencoba beberapa hotfix selama 45 menit sebelum menghentikan perdagangan. Kemungkinan mereka tidak punya kill switch, atau tidak ada orang yang berwenang menekannya karena jika ditekan pada saat yang salah, biaya peluangnya sekitar 500 ribu dolar
Saat itu saya bekerja di pesaing Knight, dan meski kami juga sering men-deploy bug mengerikan ke lingkungan produksi, dalam postmortem sulit membayangkan hal yang sama bisa terjadi pada kami. Ada beberapa sistem otomatis yang memblokir transaksi individual, dan trader senior atau staf operasional bisa membuat kill switch ditarik hanya dengan percakapan 60 detik, tanpa perlu takut pada dampak lanjutannya
Dalam praktiknya, kami sebenarnya bisa memperoleh lebih banyak dari kerugian Knight sebesar 400 juta dolar, tetapi sistem risiko kami menilai itu “terlalu bagus untuk dipercaya” dan terus mematikan strategi, sehingga laba kami berkurang
Perlu melihat lagi bagian “salah satu teknisi Knight tidak menyalin kode baru ke salah satu dari 8 server SMARS”. Tentu saja pipeline CI/CD juga bisa gagal di tengah jalan sehingga hanya ter-deploy ke sebagian server, tetapi menurut saya kemungkinannya kecil
Bahkan kalaupun begitu, Ansible Playbook akan berhenti pada saat kegagalan transfer tersebut dan seluruh Playbook akan gagal, sehingga tidak akan mencapai tahap terakhir, yaitu restart layanan
Ini adalah kesalahan manusia, dan justru karena itulah otomatisasi ada
Selain itu, bagian “teknisi kedua tidak meninjau deployment, dan tidak ada yang tahu bahwa kode Power Peg tidak dihapus dari server ke-8 serta kode RLP baru juga tidak ditambahkan” juga bisa dicegah oleh CI/CD. “Pull Request” ke repositori kode Ansible akan mencegah teknisi pertama menggabungkannya ke master/main tanpa review. Karena master/main seharusnya dilindungi
Saya yakin DevOps berbasis CI/CD akan menyelesaikan masalah ini 100%
Charity Majors banyak membicarakan hal terkait ini di Euruko. Tool deployment tidak boleh sekadar skrip bash yang dibungkus mantel; harus punya cukup personel dan pengujian, serta diotomatisasi sejauh mungkin sampai ujung
Dengan proses deployment yang mendekati arsitektur immutable, tool yang memantau rollout yang gagal/terhenti/belum selesai, dan kemampuan untuk cepat kembali ke kondisi sehat sebelumnya, akan ada lapisan pertahanan dan jalur tindakan menjadi lebih mudah ketika sesuatu berjalan salah. Masalah ini tidak akan menjadi mustahil, tetapi akan lebih sulit terjadi
Prosedur eksekusi manual berubah menjadi permainan tebak-tebakan setiap kali bekerja di server: “Saya sudah melakukan langkah 12, sepertinya langkah 13 juga sudah, jadi berikutnya langkah 14.” Otak manusia sering kali tidak bisa secara andal membedakan eksekusi kali ini dari ingatan palsu yang muncul dari pekerjaan yang sudah dilakukan sejuta kali ketika terputus di tengah jalan
Jika tidak ada interlock yang mencegah langkah dilewati, setiap kali itu adalah perjudian. Dan upaya membuat interlock sudah mencakup sebagian besar biaya otomatisasi
“Mengapa kode yang sudah mati selama 8 tahun masih ada di codebase memang misteri, tapi itu bukan poin utamanya,” katanya, namun justru ini terlihat sebagai poin utamanya
Sepertinya mereka membiarkan kode yang tidak dipakai selama 8 tahun, lalu baru mencoba menghapusnya ketika hendak memakai ulang flag. Kalau 8 tahun sebelumnya mereka menanganinya dengan benar dan menghapus kode yang tidak dipakai, ceritanya akan sangat berbeda. Tidak akan ada rutin lama yang hidup kembali, dan tidak akan ada server yang bertingkah semaunya
Mungkin Knight Capital tidak memakai version control sehingga mempertahankan kode “untuk berjaga-jaga”. Namun bahkan di repositori yang sepenuhnya memakai version control, saya pernah melihat developer enggan menghapus kode, dan itu benar-benar mengejutkan. Kalau nanti dibutuhkan lagi, tinggal pulihkan dari version control. Kalau dibutuhkan lagi tetapi mereka lupa bahwa kode itu ada di sana, mereka juga tidak akan menemukan jalur kode mati itu. Membiarkannya di source tree adalah utang murni
Kevlin Henney pernah memberikan presentasi bagus di GOTO tentang keandalan perangkat lunak, dan membahas poin ini dengan Knight Capital sebagai contoh. Ia bahkan mengutip tulisan blog ini https://youtu.be/IiGXq3yY70o?si=hZ9HB2dlfj0vHvNK&t=463
“Tidak ada kode yang benar-benar mati. Cukup satu asumsi kecil, satu perubahan asumsi, dan tiba-tiba itu bukan lagi kode mati, melainkan kode zombi. Kiamat zombi yang bangkit kembali itu mahal”
git log, dan mungkin memakaigit blameMereka sering tidak tahu cara memfilter riwayat git. Mereka tidak tahu
git pickaxeatau pola pengecualian, dan bahkan tidak terpikir bahwa mereka bisa mencarifoodi git log sambil mengecualikan direktori tertentu, sepertigit log -G'int.*foo\(' -- ':(exclude)directory'Sebaliknya, mereka tahu cara melakukan
grepdi tree kode saat ini. Jadi mereka mengira selama tidak dihapus, kode itu bisa ditemukan lagi dengangrepyang tepat. Kalau dihapus, mereka mungkin tidak tahu cara menemukannya di riwayat gitSampai titik tertentu ini bisa dimengerti. Kode di dalam git log tidak terlihat oleh banyak tool. Misalnya, editor tidak akan menyarankannya lewat autocomplete, dan kode itu juga tidak muncul di dokumentasi library
Kalau benar-benar percaya kode itu akan dipakai lagi, mempertahankannya di tree agar ikut refactoring dan bisa ditemukan saat diperlukan masih bisa sedikit dibela. Namun dalam kasus seperti Knight Capital, ketika jelas-jelas tidak akan dipakai lagi, itu sulit dibela
Update yang sekadar “menghapus kode lama” pun bisa terasa sulit bagi orang yang melihat perubahan apa pun sebagai risiko kerusakan. Secara adil, setiap perubahan memang berisiko, tetapi membiarkan kode lama juga berisiko
Setidaknya sekarang kita bisa menunjuk kasus ini sebagai contoh risiko yang jelas
Yang benar-benar tidak saya pahami setiap kali melihat kisah ini adalah keputusan untuk memakai ulang flag yang sudah ada, bukan membuat flag baru. Kenapa mereka melakukan itu?
git rebaseSaya berharap kebanyakan organisasi punya proses untuk mencegah hal seperti itu terjadi di sekitar branch utama. Namun saya sendiri pernah tanpa sengaja merusak tabel database produksi di organisasi kecil, jadi
git rebaseyang tidak disengaja pun sulit dianggap mustahilAda masalah lain: mereka memakai database yang hanya memiliki 256 kolom. Ketika butuh kolom baru, mereka sering begitu saja memakai ulang kolom lama yang “saat itu tidak digunakan”
Kalau ingatan saya benar, secara internal pun hal itu umumnya diakui sebagai “ide buruk”, tetapi tidak ada yang memprioritaskan pembersihan kode lama atau penerapan praktik terbaik yang lebih baik
Tidak ada sistem continuous deployment yang pernah saya alami yang akan mencegah bug khusus ini
Mereka memang melakukan rollout bertahap, tetapi di dalam kode ada bug logika yang berarti jika satu instalasi gagal pada tahap rollout bertahap itu, perusahaan bisa bangkrut
Untuk mencegahnya, mereka perlu memeriksa saat runtime apakah versi software, misalnya git SHA, cocok, dan menambahkan fault injection pada pengujian yang memanggil infrastruktur rollout software
Saat itu benar-benar seperti Wild West. Penting juga dicatat bahwa sejak itu sistem perdagangan sudah banyak berubah
Ketika saya mulai bekerja di bidang ini pada 2009, keandalan sistem di bank, broker, dan bursa semuanya cukup berantakan. Sering kali kami harus mengonfirmasi lewat telepon berapa jumlah eksekusi transaksi
Saya ingat ketika bursa Italia sedang melakukan rollout sistem. Pada satu titik mereka melakukan “pengujian” di lingkungan yang campuran antara produksi dan UAT, dan kalau ingatan saya benar, setelah pasar tutup mereka hanya mengubah IP koneksi pengiriman order untuk mencoba rilis berikutnya. Lingkungan UAT terlalu banyak bug dan sebagian besar setengah mati, sehingga tidak bisa dipakai untuk pengujian
Jangan mulai bahas spreadsheet Excel dengan kode VBA yang bahkan ChatGPT pun akan maki-maki, yang dipakai untuk memberi harga produk dengan volume transaksi yang punya deretan nol sangat panjang
Sekarang sangat berbeda. Sebagian juga berkat insiden-insiden seperti ini. Sebagian besar sudah otomatis, dan sikap koboi jauh berkurang
Ada kill switch wajib, berlapis-lapis pemantauan risiko/aktivitas perdagangan, pemantauan dari sisi bursa, dan sangat banyak pelajaran yang dipetik dengan susah payah benar-benar tercermin dalam sistem. Itu juga alasan orang cenderung naif dalam memandang sulitnya membuat sistem perdagangan yang baik. Strateginya memang makin cerdas, tetapi intinya biasanya adalah bagaimana agar tidak mati karena sesuatu di luar kondisi normal
Secara harfiah semua orang di keuangan kuantitatif tahu Knight Capital. Ada juga ungkapan “pulling a knight capital”. Artinya, bahkan dalam sistem mission-critical yang bisa membuat perusahaan bangkrut seketika, orang masih mengambil jalan pintas lalu membayar akibatnya
Sistem tim kami memainkan peran penting dalam pendapatan ratusan juta dolar per hari. Jika sistem down cukup lama, pendapatan itu hilang. Yang dimaksud cukup lama di sini setidaknya beberapa jam, dan dalam rentang waktu itu biasanya kami bisa mengembalikannya ke kondisi normal tanpa dampak eksternal yang besar
Kami juga punya proses manual, tetapi untuk proses manual apa pun, sebelum memulai kami mendokumentasikan prosedur rollback dan memantau deployment. Kami juga memisahkan deployment kode dan deployment fitur, dan deployment fitur dilakukan bertahap di balik feature flag
Untuk fitur baru atau perubahan kode, kami mewajibkan feature flag baru. Ini menyakitkan dan lambat, tetapi membantu kami menghindari situasi berbahaya dan kepanikan, serta sangat mengurangi beban operasional dan on-call
Agar benar-benar kacau parah, harus melewati beberapa “filter cacat”. Misalnya code review melewatkan perubahan perilaku tanpa feature flag, pengujian manual/lingkungan pengembangan juga melewatkannya, deployment gagal, rollback gagal atau salah, tidak ada pemantauan yang memberi tahu bahwa masalah belum diperbaiki, gagal melakukan eskalasi ke tingkat lebih tinggi tepat waktu, lalu cukup waktu berlalu hingga kehilangan kemampuan memenuhi SLA
Untuk perubahan manual yang lebih berisiko, bisa juga dua orang melakukan perubahan bersama. Satu orang menunjukkan lewat video call apa yang diubah, dan orang lain memverifikasi
Jika menangani sistem dengan SLA dalam hitungan menit dan perubahan yang tidak bisa dibatalkan, Anda harus tahu cara praktis untuk memantau dan melakukan rollback dalam beberapa menit. Jika itu pekerjaan baru dan manual, periksa empat kali, dan minta orang lain mengawasi di samping Anda. Kalau tidak, hanya soal waktu sampai beberapa masalah bertumpuk berurutan dan datang momen yang tidak bisa diperbaiki. Sepintar dan sehebat apa pun, jika manusia harus mengubah secara manual atau memulai perubahan, kesalahan akan selalu terjadi, dan probabilitas kesalahan itu harus tertanam dalam proses change management
Dalam perdagangan umum atau B2B, dalam banyak kasus pelanggan bisa mencoba pembelian yang sama lagi sedikit kemudian. Bukan “sekarang atau tidak sama sekali”
Saya juga pernah mencoba lagi membeli sesuatu yang saya inginkan ketika penjual sedang down, server jebol karena pengumuman baru dan lonjakan permintaan, atau ada masalah pemeliharaan bank
Tulisan terkait:
Knightmare: A DevOps Cautionary Tale (2014) - https://news.ycombinator.com/item?id=22250847 - Februari 2020, 33 komentar
Knightmare: A DevOps Cautionary Tale (2014) - https://news.ycombinator.com/item?id=8994701 - Februari 2015, 85 komentar
Knightmare: A DevOps Cautionary Tale - https://news.ycombinator.com/item?id=7652036 - April 2014, 60 komentar
Tambahan:
The $440M software error at Knight Capital (2019) - https://news.ycombinator.com/item?id=31239033 - Mei 2022, 172 komentar
Bugs in trading software cost Knight Capital $440M - https://news.ycombinator.com/item?id=4329495 - Agustus 2012, 1 komentar
Knight Capital Says Trading Glitch Cost It $440 Million - https://news.ycombinator.com/item?id=4329101 - Agustus 2012, 90 komentar
Ada yang lain?
Nanex ~ 03-Aug-2012 ~ The Knightmare Explaned - https://news.ycombinator.com/item?id=4337359 - tidak ada komentar
Masalah sebenarnya, kalau boleh memakai ungkapan ala “No true Scotsman”, adalah mereka menggunakan kombinasi konfigurasi dan rilis binary yang belum diuji
Konfigurasi dan binary bisa di-rollout secara serempak, dan dengan begitu masalah semacam ini bisa dicegah. Tentu ada kesalahan-kesalahan lain juga, tetapi tanpa kondisi ini, masalah ini tidak mungkin terjadi
Bagian “Mengapa kode yang sudah mati selama 8 tahun masih ada di codebase adalah misteri, tetapi itu bukan inti masalah” mungkin bukan kesalahan terburuk dalam cerita ini, tetapi juga tidak bisa dibilang bukan inti
Jika fitur mati itu dipotong secara proaktif, perangkat lunaknya akan menjadi lebih sederhana dan lebih mudah dipahami, dan kemungkinan lepas kendali juga lebih kecil. Terus maju tanpa henti tanpa pemeliharaan seperti ini adalah risiko, entah disengaja sebagai perhitungan atau tidak
Saya benar-benar bersyukur tidak menulis kode yang secara otomatis merutekan jutaan dolar tanpa campur tangan manusia
Rasanya seperti menulis kode yang menerbangkan jet jumbo. Siapa yang mau memikul tanggung jawab seperti itu
Menurut saya ini cocok untuk tipe orang tertentu yang mencintai proses, pengujian, simulator, dan redundansi. Di tempat seperti itu, kode yang menerbangkan pesawat sendiri hanyalah 1% dari rekayasa
Anda tinggal menyelesaikan satu per satu kekhawatiran yang muncul secara alami, dan semakin masuk akal rasa cemas Anda, semakin baik bagi bisnis. Berdasarkan pengalaman di sektor keuangan, menurut saya masalah Knight adalah 10% masalah teknis dan 90% masalah seseorang semacam CTO yang salah mengira dirinya berani. Bukan hanya hari itu atau minggu itu, tetapi secara umum
Saya rasa insiden ini juga sedikit banyak berperan dalam hal itu