Knightmare: Câu chuyện cảnh báo về DevOps (2014)
(dougseven.com)- Knight Capital Group, một trụ cột lớn của giao dịch cổ phiếu Mỹ, đã bị đẩy đến bờ vực phá sản vào ngày 1 tháng 8 năm 2012 khi triển khai SMARS thất bại gây ra khoản lỗ 460 triệu USD chỉ trong 45 phút
- Trong quá trình ứng phó với Retail Liquidity Program của NYSE, việc tái sử dụng cờ của mã Power Peg vốn không dùng suốt 8 năm cho tính năng mới đã trở thành điểm khởi đầu của sự cố
- Mã mới chỉ được triển khai lên 7 trong 8 máy chủ, và khi máy chủ còn lại nhận lệnh RLP mới, chức năng Power Peg tưởng như đã chết lại được kích hoạt
- Power Peg tiếp tục định tuyến các lệnh con mà không theo dõi khối lượng khớp của lệnh cha, và Knight buộc phải tìm nguyên nhân ngay trong môi trường production mà không có kill switch hay quy trình ứng phó được tài liệu hóa
- Triển khai quan trọng không kém gì viết mã và kiểm thử; triển khai dựa vào quy trình thủ công, nếu thiếu tự động hóa, khả năng lặp lại và xác minh, sẽ trở thành rủi ro vận hành chí mạng
Công ty giao dịch tốc độ cao sụp đổ trong 45 phút
- Knight Capital Group là công ty dịch vụ tài chính Mỹ hoạt động trong lĩnh vực tạo lập thị trường, thực thi điện tử, bán hàng và giao dịch tổ chức
- Năm 2012, Knight là nhà giao dịch lớn nhất tại thị trường cổ phiếu Mỹ với khoảng 17% thị phần trên cả NYSE và NASDAQ
- Electronic Trading Group (ETG) của Knight xử lý trung bình hơn 3,3 tỷ giao dịch mỗi ngày và giao dịch hơn 21 tỷ USD mỗi ngày
- Tính đến ngày 31 tháng 7 năm 2012, Knight nắm giữ khoảng 365 triệu USD tiền mặt và tài sản tương đương tiền
Cập nhật SMARS để đáp ứng RLP
- NYSE dự kiến khởi động Retail Liquidity Program vào ngày 1 tháng 8 năm 2012
- Knight đã cập nhật SMARS, bộ định tuyến thuật toán tốc độ cao tự động gửi lệnh ra thị trường, để đáp ứng thay đổi này
- SMARS là hệ thống nhận “lệnh cha” từ nền tảng giao dịch rồi chia chúng thành một hoặc nhiều “lệnh con” để thực thi
- Lệnh cha càng lớn thì càng tạo ra nhiều lệnh con
- Bản cập nhật lần này nhằm thay thế mã Power Peg vốn đã không được dùng trong 8 năm
- Mã mới tái sử dụng cờ cũ từng dùng để kích hoạt Power Peg cho chức năng mới
- Bản thân mã đã được kiểm thử đầy đủ và xác nhận hoạt động bình thường
Một máy chủ bị bỏ sót trong đợt triển khai thủ công
- Từ ngày 27 tháng 7 đến ngày 31 tháng 7 năm 2012, Knight triển khai thủ công phần mềm mới lên số lượng máy chủ giới hạn mỗi ngày, với tổng cộng 8 máy chủ mục tiêu
- Theo tài liệu của SEC, một kỹ thuật viên đã không sao chép mã mới lên một trong 8 máy chủ SMARS
- Không có quy trình để kỹ thuật viên thứ hai rà soát đợt triển khai này, và cũng không có quy trình được tài liệu hóa yêu cầu việc rà soát như vậy
- Kết quả là trên máy chủ thứ 8, mã Power Peg không bị gỡ bỏ và mã RLP mới cũng không được thêm vào
Cách đoạn mã đã chết sống lại
- Khi thị trường mở cửa lúc 9 giờ 30 sáng ngày 1 tháng 8 năm 2012 (giờ miền Đông Hoa Kỳ), Knight bắt đầu xử lý lệnh của khách hàng broker-dealer cho Retail Liquidity Program
- 7 máy chủ được triển khai đúng cách xử lý lệnh bình thường
- Các lệnh đi vào máy chủ thứ 8 đã kích hoạt lại mã Power Peg cũ thông qua cờ được tái sử dụng
- Ban đầu, Power Peg có chức năng đếm số cổ phiếu đã mua hoặc bán so với lệnh cha khi các lệnh con được thực thi, rồi dừng định tuyến lệnh con khi lệnh cha đã được đáp ứng
- Năm 2005, Knight đã chuyển chức năng theo dõi cộng dồn lên bước sớm hơn trong luồng thực thi mã, và phần theo dõi tổng hợp bên trong Power Peg đã bị loại bỏ
- Khi cờ Power Peg được kích hoạt trên máy chủ thứ 8, Power Peg định tuyến các lệnh con tới thị trường thực thi nhưng không theo dõi số lượng cổ phiếu so với lệnh cha, nên về thực chất nó hoạt động như một vòng lặp vô tận
Tín hiệu trước giờ mở cửa và cơn bùng nổ sau 9:30
- Hệ thống của Knight bắt đầu gửi email tự động từ 8:01 sáng hôm đó
- Điều này xảy ra khi SMARS xử lý các lệnh giao dịch trước giờ mở cửa
- Email nhắc đến SMARS và xác định lỗi là “Power Peg disabled”
- Từ 8:01 đến 9:30, 97 email như vậy đã được gửi đến nhân viên Knight
- Những email này không được thiết kế như cảnh báo hệ thống nên đã không được kiểm tra ngay
- Ngay sau khi thị trường mở cửa lúc 9:30, nhiều người ở Wall Street đã nhận ra có điều bất thường
- Đến 9:31, việc đang xảy ra một sự cố nghiêm trọng đã trở nên rõ ràng, và đến 9:32, câu hỏi vì sao nó không dừng lại ngày càng lớn
- Trong 45 phút đầu tiên, hoạt động thực thi của Knight chiếm hơn 50% khối lượng giao dịch ở một số mã cổ phiếu và đẩy giá một số cổ phiếu tăng hơn 10%
- Để phản ứng với các giao dịch sai lệch, giá trị của các cổ phiếu khác lại sụt giảm
Thiếu kill switch và cách ứng phó sai lầm
- Knight không có kill switch để dừng ngay hệ thống gặp sự cố
- Cũng không có quy trình ứng phó được tài liệu hóa, nên họ phải chẩn đoán nguyên nhân ngay trong môi trường production nơi có 8 triệu cổ phiếu được giao dịch mỗi phút
- Không tìm ra nguyên nhân, Knight đã gỡ mã mới khỏi các máy chủ vốn được triển khai đúng cách
- Hành động này dẫn đến việc gỡ bỏ mã đang hoạt động bình thường và giữ nguyên mã có vấn đề
- Sau đó, các lệnh cha bổ sung đã kích hoạt mã Power Peg không chỉ trên một máy chủ mà trên tất cả máy chủ, khiến vấn đề còn nghiêm trọng hơn
- Knight chỉ có thể dừng hệ thống sau 45 phút
Quy mô thiệt hại và cái kết của công ty
- Trong 45 phút đầu sau khi thị trường mở cửa, mã Power Peg đã nhận và xử lý 212 lệnh cha
- SMARS đã gửi hàng triệu lệnh con ra thị trường, dẫn tới 4 triệu giao dịch trên 154 mã cổ phiếu và khối lượng hơn 397 triệu cổ phiếu
- Knight gánh vị thế mua ròng khoảng 3,5 tỷ USD trên 80 mã cổ phiếu và vị thế bán ròng khoảng 3,15 tỷ USD trên 74 mã cổ phiếu
- Knight Capital Group đã hiện thực hóa khoản lỗ 460 triệu USD chỉ trong 45 phút
- Vì khi đó công ty chỉ nắm giữ 365 triệu USD tiền mặt và tài sản tương đương tiền, Knight đã từ nhà giao dịch cổ phiếu lớn nhất nước Mỹ và một nhà tạo lập thị trường quan trọng rơi vào tình trạng phá sản
- Để bù lỗ, công ty phải huy động vốn trong vòng 48 giờ, và Knight đã nhận được 400 triệu USD đầu tư từ khoảng 6 nhà đầu tư
- Sau đó, Knight Capital Group được Getco LLC mua lại vào tháng 12 năm 2012, và công ty hợp nhất trở thành KCG Holdings
Bài học cho DevOps và Continuous Delivery
- Chỉ tạo ra phần mềm tốt và kiểm thử nó là chưa đủ
- Để chuyển giao giá trị cho khách hàng, phần mềm phải được triển khai chính xác ra thị trường
- Nguyên nhân sự cố không chỉ nằm ở một kỹ sư đã triển khai SMARS, mà còn ở chỗ quy trình của Knight không thể gánh nổi mức rủi ro bị phơi bày
- Triển khai dựa vào cách con người đọc và làm theo chỉ dẫn luôn hàm chứa khả năng sai sót
- Sai sót có thể phát sinh từ chính chỉ dẫn, cách diễn giải chỉ dẫn hoặc quá trình thực hiện chỉ dẫn
- Triển khai nên được tự động hóa và có khả năng lặp lại ở mức tối đa có thể để giảm khả năng lỗi do con người
- Nếu hệ thống triển khai tự động có bao gồm tự động hóa cấu hình, triển khai và kiểm thử, Knight có thể đã tránh được lỗi gây ra Knightmare
- Có hai nguyên tắc của Continuous Delivery áp dụng cho trường hợp này
- Phát hành phần mềm phải là một quy trình có thể lặp lại và đáng tin cậy
- Cần tự động hóa càng nhiều càng tốt trong phạm vi hợp lý
1 bình luận
Ý kiến trên Hacker News
Không rõ triển khai tự động sẽ giải quyết vấn đề này như thế nào. Ngược lại, nó có khả năng còn làm mức độ ảnh hưởng và hậu quả dây chuyền lớn hơn
Nếu đổi “một lập trình viên quên đưa mã lên một máy chủ” thành “agent triển khai gặp lỗi khi tải binary/mã mới xuống máy chủ, và do bug trong agent nên lỗi đó không bị lộ ra” thì vẫn là cùng một kiểu lỗi. Ảnh hưởng có lẽ đã lan nhanh hơn
Trách nhiệm ở đây thuộc về lập trình viên. Vì họ đã viết mã theo cách không tương thích ngược
Cả thị trường lẫn Knight đều biết đang có vấn đề nghiêm trọng, nhưng họ đã thử nhiều hotfix trong suốt 45 phút trước khi dừng giao dịch. Có thể là không có kill switch, hoặc không có ai có quyền bấm vì nếu bấm sai thời điểm thì chi phí cơ hội khoảng 500.000 USD
Khi đó tôi làm ở một đối thủ của Knight; chúng tôi cũng thường xuyên đưa các bug kinh khủng lên môi trường vận hành, nhưng trong các buổi phân tích hậu sự cố, thật khó tưởng tượng chuyện tương tự có thể xảy ra với chúng tôi. Chúng tôi có nhiều hệ thống tự động để chặn từng giao dịch riêng lẻ, và một trader cấp cao hoặc người phụ trách vận hành có thể kéo kill switch chỉ sau cuộc nói chuyện 60 giây, mà không phải sợ hậu quả của việc đó
Thực ra chúng tôi có thể kiếm được nhiều hơn từ khoản lỗ 400 triệu USD của Knight, nhưng hệ thống rủi ro của chúng tôi đánh giá tình huống là “tốt đến mức khó tin” và liên tục tắt chiến lược, nên lợi nhuận bị giảm
Cần nhìn lại đoạn “một kỹ sư của Knight đã không sao chép mã mới sang một trong 8 máy chủ SMARS”. Dĩ nhiên pipeline CI/CD cũng có thể lỗi giữa chừng và chỉ triển khai lên một phần máy chủ, nhưng tôi cho rằng khả năng đó thấp
Ngay cả nếu vậy, với Ansible Playbook thì nó đã dừng ngay tại thời điểm truyền thất bại đó, toàn bộ Playbook sẽ fail, và sẽ không đi tới bước cuối cùng là khởi động lại dịch vụ
Đây là lỗi con người, và chính vì thế mà tự động hóa tồn tại
Ngoài ra, đoạn “kỹ sư thứ hai đã không rà soát việc triển khai, và không ai biết rằng mã Power Peg chưa bị gỡ khỏi máy chủ thứ 8, cũng như mã RLP mới chưa được thêm vào” cũng là điều CI/CD có thể ngăn được. “Pull Request” đối với kho mã Ansible sẽ ngăn kỹ sư đầu tiên merge vào master/main mà không được rà soát. Vì master/main phải được bảo vệ
Tôi tin chắc rằng DevOps dựa trên CI/CD đã giải quyết vấn đề này 100%
Charity Majors đã nói khá nhiều về chuyện liên quan tại Euruko. Công cụ triển khai không nên chỉ là script bash khoác áo choàng; nó cần có đủ nhân lực và kiểm thử, và phải được tự động hóa đến mức tối đa có thể
Một quy trình triển khai gần với kiến trúc bất biến, công cụ giám sát rollout thất bại/dừng lại/chưa hoàn tất, cùng khả năng nhanh chóng quay về trạng thái tốt trước đó sẽ tạo ra các lớp phòng vệ và khiến đường hành động trở nên dễ dàng khi mọi việc trục trặc. Nó không làm vấn đề này trở nên bất khả thi, nhưng sẽ khiến nó khó xảy ra hơn
Tài liệu quy trình thủ công mỗi lần làm việc với máy chủ lại biến thành trò đoán kiểu “mình đã làm bước 12, có vẻ cũng đã làm bước 13, vậy tiếp theo là bước 14”. Bộ não con người, khi một việc đã làm hàng triệu lần bị ngắt quãng giữa chừng, thường không thể phân biệt đáng tin cậy giữa lần thực hiện hiện tại và ký ức giả sinh ra từ lần trước
Nếu không có interlock để ngăn bỏ qua bước, thì lần nào cũng là đánh bạc. Và nỗ lực để tạo các interlock đó vốn đã chiếm một phần đáng kể chi phí tự động hóa
“Vì sao đoạn mã đã chết suốt 8 năm vẫn còn nằm trong codebase là một điều bí ẩn, nhưng đó không phải trọng tâm” — tuy nói vậy, nhưng tôi thấy đây chính xác là trọng tâm
Có vẻ họ đã để nguyên đoạn mã không dùng suốt 8 năm, rồi chỉ đến khi muốn tái sử dụng flag mới định gỡ bỏ nó. Nếu 8 năm trước họ xử lý đúng và xóa đoạn mã không dùng đó đi, câu chuyện hẳn đã hoàn toàn khác. Routine cũ đã không sống lại, và cũng đã không có những server tự ý làm theo cách riêng
Có thể Knight Capital không dùng quản lý phiên bản nên cứ giữ mã lại “phòng khi cần”. Nhưng tôi cũng từng thấy các developer không muốn xóa mã ngay cả trong repository được quản lý phiên bản đầy đủ, và điều đó thật sự đáng kinh ngạc. Nếu cần lại thì khôi phục từ quản lý phiên bản là được. Nếu cần lại mà lại quên mất nó từng ở đó, thì họ cũng sẽ không tìm ra được đường mã đã chết kia. Để nó lại trong source tree thuần túy là nợ
Kevlin Henney có một bài thuyết trình rất hay tại GOTO về độ tin cậy phần mềm, trong đó dùng Knight Capital làm ví dụ và bàn đúng điểm này. Thực ra ông cũng trích dẫn bài blog này https://youtu.be/IiGXq3yY70o?si=hZ9HB2dlfj0vHvNK&t=463
“Không có thứ gì là mã chết thật sự. Chỉ cần một giả định nhỏ, một thay đổi nhỏ trong giả định, và đột nhiên nó không còn là mã chết nữa mà thành mã zombie. Một tận thế zombie được hồi sinh sẽ tốn tiền”
git log, và có lẽ biết dùnggit blameNhiều người không biết cách lọc lịch sử git. Họ không biết
git pickaxehay các mẫu loại trừ, thậm chí không nghĩ rằng có thể tìmfootrong git log nhưng loại trừ một thư mục cụ thể, nhưgit log -G'int.*foo\(' -- ':(exclude)directory'Thay vào đó, họ biết cách
greptrong cây mã hiện tại. Vì vậy họ nghĩ nếu không xóa thì sau này có thể tìm lại bằng một lệnhgrepphù hợp. Còn nếu đã xóa, có thể họ không biết cách tìm trong lịch sử gitỞ mức nào đó thì cũng hiểu được. Mã trong git log không hiện ra trong nhiều công cụ. Ví dụ, editor sẽ không gợi ý nó qua autocomplete, và nó cũng không xuất hiện trong tài liệu thư viện
Nếu thật sự tin rằng đoạn mã đó sẽ được dùng lại, thì việc để nó trong tree để nó đi theo các lần refactor và được phát hiện khi cần cũng có thể biện hộ được phần nào. Nhưng trong trường hợp rõ ràng sẽ không bao giờ dùng lại như Knight Capital thì rất khó biện hộ
Ngay cả một cập nhật chỉ đơn giản là “xóa mã cũ” cũng có thể khiến những người cho rằng bất kỳ thay đổi nào cũng tạo rủi ro hỏng hóc cảm thấy khó chấp nhận. Công bằng mà nói, mọi thay đổi đều có rủi ro, nhưng để mã cũ lại cũng là rủi ro
Ít nhất giờ ta có thể chỉ thẳng vào trường hợp này như một ví dụ rõ ràng về rủi ro
Điều tôi thật sự không hiểu mỗi khi đọc câu chuyện này là họ tái sử dụng flag hiện có thay vì tạo một flag mới. Vì sao lại làm vậy?
git rebaseHy vọng hầu hết tổ chức có quy trình để chuyện đó không xảy ra quanh nhánh main. Nhưng bản thân tôi từng vô tình làm hỏng một bảng cơ sở dữ liệu vận hành ở một tổ chức nhỏ, nên cũng khó coi một cú
git rebasengoài ý muốn là chuyện không thể xảy raCòn có một vấn đề khác là họ dùng cơ sở dữ liệu chỉ có 256 cột. Khi cần cột mới, họ thường chỉ tái sử dụng một cột cũ “lúc đó không dùng”
Nếu tôi nhớ đúng, nội bộ nhìn chung cũng thừa nhận đó là “ý tưởng tồi”, nhưng không ai ưu tiên việc dọn mã cũ hay thiết lập các best practice tốt hơn
Không có hệ thống triển khai liên tục nào tôi từng gặp có thể ngăn được bug cụ thể này
Đúng là họ đang rollout dần dần, nhưng trong mã có một bug logic mà nếu một lần cài đặt thất bại trong giai đoạn rollout dần dần đó thì công ty sẽ phá sản
Để ngăn chuyện này, lẽ ra cần kiểm tra tại thời điểm chạy rằng các phiên bản phần mềm, chẳng hạn git SHA, khớp nhau, và thêm cả fault injection vào các test gọi đến hạ tầng rollout phần mềm
Đó đúng là thời miền Tây hoang dã. Cũng cần nhấn mạnh rằng kể từ đó, hệ thống giao dịch đã thay đổi rất nhiều
Khi tôi bắt đầu làm trong lĩnh vực này vào năm 2009, độ tin cậy hệ thống của ngân hàng, broker và sàn giao dịch đều khá tệ. Chuyện phải gọi điện để xác nhận khối lượng khớp lệnh là bao nhiêu xảy ra thường xuyên
Tôi nhớ thời sàn giao dịch Ý rollout hệ thống. Có lúc họ “test” trong một môi trường lẫn lộn giữa production và UAT, và nếu tôi nhớ đúng thì sau khi đóng cửa thị trường, họ chỉ đổi IP kết nối gửi lệnh để thử bản phát hành tiếp theo. Môi trường UAT quá nhiều bug và phần lớn nửa sống nửa chết nên không thể test ở đó
Đừng nói đến những bảng tính Excel chứa mã VBA mà đến ChatGPT cũng phải chửi, dùng để định giá sản phẩm với khối lượng giao dịch có cả đống số 0
Ngày nay thì rất khác. Một phần cũng nhờ những sự cố như thế này. Phần lớn đã được tự động hóa, và thái độ kiểu cao bồi cũng ít đi rất nhiều
Có kill switch bắt buộc, nhiều lớp giám sát rủi ro/hoạt động giao dịch, giám sát phía sàn giao dịch, và rất nhiều bài học trả giá đắt đã thật sự được đưa vào hệ thống. Đây cũng là lý do mọi người thường nhìn quá ngây thơ về độ khó của việc xây dựng một hệ thống giao dịch tốt. Chiến lược thông minh hơn là một chuyện, nhưng cốt lõi thường là làm sao để không chết vì một thứ nằm ngoài điều kiện bình thường
Theo đúng nghĩa đen, mọi người trong tài chính định lượng đều biết Knight Capital. Còn có cả cụm “pulling a knight capital”. Tức là chọn đường tắt ngay cả trong các hệ thống mission-critical có thể khiến công ty phá sản trong chớp mắt, rồi phải trả giá cho điều đó
Hệ thống của đội chúng tôi đóng vai trò then chốt đối với doanh thu hàng trăm triệu đô la mỗi ngày. Nếu hệ thống ngừng hoạt động đủ lâu, khoản doanh thu đó sẽ biến mất. Ở đây “đủ lâu” nghĩa là ít nhất vài giờ, và trong khoảng thời gian đó thường có thể đưa hệ thống về trạng thái bình thường mà không gây ảnh hưởng lớn ra bên ngoài.
Chúng tôi cũng có quy trình thủ công, nhưng với bất kỳ quy trình thủ công nào, trước khi bắt đầu cũng phải lập tài liệu quy trình rollback và giám sát triển khai. Chúng tôi cũng tách riêng triển khai mã và triển khai tính năng; việc triển khai tính năng được thực hiện dần dần phía sau feature flag.
Tính năng mới hoặc thay đổi mã đều yêu cầu feature flag mới. Việc này đau đớn và chậm chạp, nhưng đã giúp tránh các tình huống nguy hiểm và hoảng loạn, đồng thời giảm đáng kể gánh nặng vận hành và on-call.
Để thật sự hỏng nghiêm trọng, phải vượt qua nhiều “bộ lọc lỗi”. Chẳng hạn code review bỏ sót một thay đổi hành vi không có feature flag, kiểm thử thủ công/môi trường phát triển cũng bỏ sót, triển khai thất bại, rollback thất bại hoặc sai, không có giám sát để cảnh báo rằng vấn đề vẫn chưa được khắc phục, không kịp escalation lên cấp cao hơn, rồi đủ thời gian trôi qua khiến mất khả năng đáp ứng SLA.
Với các thay đổi thủ công nguy hiểm hơn, có thể yêu cầu hai người cùng thực hiện thay đổi. Một người chỉ ra qua cuộc gọi video đang thay đổi gì, người kia xác minh.
Nếu đang xử lý một hệ thống có SLA tính bằng phút và thay đổi không thể hoàn tác, bạn phải biết cách thực tế để giám sát và rollback trong vài phút. Nếu đó là một tác vụ mới và thủ công, hãy kiểm tra bốn lần và để người khác đứng cạnh quan sát. Nếu không, việc nhiều vấn đề nối tiếp chồng lên nhau đến thời điểm không thể sửa được chỉ là vấn đề thời gian. Dù con người có xuất sắc và thông minh đến đâu, nếu phải thay đổi thủ công hoặc khởi động thay đổi, sai sót luôn xảy ra, và xác suất sai sót đó phải được tích hợp vào quy trình quản lý thay đổi.
Trong thương mại thông thường hoặc B2B, nhiều trường hợp khách hàng có thể thử lại cùng giao dịch mua đó muộn hơn một chút. Không phải kiểu “không mua ngay bây giờ thì mãi mãi không còn cơ hội”.
Tôi cũng từng thử mua lại thứ mình muốn khi bên bán bị sập, máy chủ vỡ trận vì thông báo mới và nhu cầu lớn, hoặc có vấn đề bảo trì ngân hàng.
Bài liên quan:
Knightmare: A DevOps Cautionary Tale (2014) - https://news.ycombinator.com/item?id=22250847 - tháng 2 năm 2020, 33 bình luận
Knightmare: A DevOps Cautionary Tale (2014) - https://news.ycombinator.com/item?id=8994701 - tháng 2 năm 2015, 85 bình luận
Knightmare: A DevOps Cautionary Tale - https://news.ycombinator.com/item?id=7652036 - tháng 4 năm 2014, 60 bình luận
Thêm nữa:
The $440M software error at Knight Capital (2019) - https://news.ycombinator.com/item?id=31239033 - tháng 5 năm 2022, 172 bình luận
Bugs in trading software cost Knight Capital $440M - https://news.ycombinator.com/item?id=4329495 - tháng 8 năm 2012, 1 bình luận
Knight Capital Says Trading Glitch Cost It $440 Million - https://news.ycombinator.com/item?id=4329101 - tháng 8 năm 2012, 90 bình luận
Còn bài nào khác không?
Nanex ~ 03-Aug-2012 ~ The Knightmare Explaned - https://news.ycombinator.com/item?id=4337359 - không có bình luận
Vấn đề thật sự, nếu chấp nhận cách nói kiểu “người Scotland chân chính”, là họ đã dùng một tổ hợp cấu hình và bản phát hành binary chưa được kiểm thử.
Cấu hình và binary có thể được rollout đồng bộ cùng lúc, và khi đó có thể ngăn được loại vấn đề này. Tất nhiên còn có những sai lầm khác, nhưng nếu không có điều kiện này thì sự cố này đã không thể xảy ra.
Đoạn “Vì sao đoạn mã đã chết suốt 8 năm vẫn còn trong codebase là một bí ẩn, nhưng đó không phải điểm mấu chốt” không phải sai lầm tệ nhất trong câu chuyện, nhưng cũng không thể nói là không cốt lõi.
Nếu chủ động cắt bỏ tính năng đã chết, phần mềm sẽ đơn giản hơn, dễ hiểu hơn, và khả năng mất kiểm soát cũng giảm đi. Việc cứ liên tục tiến về phía trước mà không bảo trì như vậy, dù có được tính toán hay không, đều là rủi ro.
Thật mừng là tôi không viết mã tự động định tuyến hàng triệu đô la mà không có con người can thiệp.
Cảm giác như viết mã để lái một máy bay phản lực cỡ lớn. Ai lại muốn gánh trách nhiệm như vậy chứ.
Tôi nghĩ đây là việc phù hợp với một kiểu người nhất định, những người yêu quy trình, kiểm thử, simulator và tính dự phòng. Bản thân mã lái máy bay chỉ chiếm 1% phần kỹ thuật ở đó.
Chỉ cần lần lượt giải quyết những nỗi lo tự nhiên xuất hiện; càng lo lắng một cách hợp lý thì càng tốt cho doanh nghiệp. Theo kinh nghiệm trong ngành tài chính của tôi, vấn đề của Knight là 10% vấn đề kỹ thuật và 90% là vấn đề một người kiểu CTO nhầm lẫn sự liều lĩnh với táo bạo. Không chỉ riêng ngày đó hay tuần đó, mà nói chung là vậy.
Tôi đoán vụ này cũng góp phần ở mức nào đó.