FinTechSep 9, 202610 dk okuma

Ani Yük Altında L2 Piyasa Verisi: Sequence Gap, Kurtarma ve Yüzlerce Oturuma Fan-Out

Piyasa VerisiOrder BookTrading AltyapısıFan-Out
Görsel yüklenemedi

Ani yük altında order book güncellemelerini düşüren ve sıralarını bozan bir handler, genellikle tek bir belirtinin arkasındaki iki ayrı arızadır: alım tarafında sıra numarası işleme ve tek bir yavaş oturumun diğer tüm oturumların aldığını değiştirdiği bir dağıtım katmanı. Sıra numarası, kurtarma, fan-out ve back pressure bu şekilde kurulur; conflation da işte burada dürüst olmaktan çıkar.

Ani yük altında L2 güncellemelerini düşüren ve sıralarını bozan bir handler, genellikle tek bir belirtinin arkasındaki iki ayrı arızadır. Biri, besleme sıra numarasının izlendiği ve bir gap'in emilmek yerine tespit edilmesi gereken alım tarafında yaşar. Diğeri, tek bir normalize defterin birçok oturuma fan-out edildiği ve tek bir yavaş okuyucunun diğerlerinin aldığını değiştirdiği dağıtım tarafında yaşar.

Çözümleri farklıdır ve yanlış olanı uygulamak belirtiyi ortadan kaldırmak yerine yerini değiştirir. Aşağıda, sıra numarasının ani bir yükten sağ çıkması gerektiğinde hattın nasıl göründüğü var: bir gap aslında nedir, kurtarma bir snapshot'ı canlı bir akışa nasıl ekler, fan-out sıralamayı nasıl tek seferde belirler ve conflation nerede dürüsttür.

Kısa yanıt yapısaldır. Sıralamaya tam olarak tek bir yerde, her oturumun yukarısında karar verilir: enstrüman başına tek bir yazıcı, numaralı beslemeyi bir deftere işler ve oturumlar bu yazımdan türetilen görünümleri alır - kendi başlarına hiçbir şeyi yeniden sıralamazlar. amBrain'in kamuya kanıtlayabildikleri: kurduğumuz bir mini borsa MOEX kolokasyonunda üretimde çalışıyor, Spectre Trade trading terminalini biz kurduk ve yayımladığımız piyasa verisi latency'si ölçüme dayanıyor - kurduğumuz yollarda 5 ms altında. Bu rakam bizim yollarımızı tarif eder, aşağıdaki tasarımın bir kıyaslamasını değil.

Sıra numarası sıralamayı vaat eder, teslimi değil

Beslemeler güncellemelerini numaralandırır ve elinizdeki tek sıralama otoritesi o numaradır. Geliş zamanı bir otorite değildir: multicast yolları sırayı bozar, tek bir enstrümanı birden çok kanal taşır, alım kuyrukları çekirdeklere dağılır ve ani yük bunların hepsini esnetir. Gelişe göre sıralayan bir handler yalnızca ağ sakinken doğrudur - yani kimsenin endişelenmediği koşulda.

Kurtarma mantığı yazılmadan önce beslemenin altı özelliği bilinmelidir. Her biri, bir gap'in ne anlama geldiğini değiştirir.

  • Sıra numarasının kapsadığı birim - kanal, enstrüman ya da defter. Kanal başına bir numara hangi enstrümanın güncelleme kaybettiğini söylemez; enstrüman başına bir numara da bir kanalın durduğunu söylemez
  • Artış kuralı: birim içinde kesin ardışık ya da izin verilen deliklerle artan. İkisi de vardır ve ikincisini birincisi diye okumak, hiç gerekmeyen kurtarmalar üretir
  • Numaraların seans sınırında yeniden başlayıp başlamadığı ve bunu neyin işaretlediği - gap diye okunan bir yeniden başlama, aynı anda her enstrümanı kurtarmaya gönderir
  • Heartbeat'lerin güncel sıra numarasını taşıyıp taşımadığı. Taşımıyorlarsa, ölü bir bağlantı ile sessiz bir enstrüman birbirinin aynısı görünür
  • Yeniden iletimin var olup olmadığı ve hangi pencerede olduğu. Yoksa geri dönüşün tek yolu snapshot ile kurtarmadır ve sık kullanılacak kadar ucuz olması gerekir
  • Bir snapshot'ın hangi sıra numarasıyla hizalandığı. O olmadan bir snapshot canlı bir akışa hiç eklenemez

Bir özellik gerçekten bilinmiyorsa, bir tahmini koda gömmek yerine ölçün. Altı özelliğin her biri kurtarma yolunda bir dala dönüşür ve oradaki yanlış bir varsayım sonradan, borsayla sessizce anlaşmazlığa düşen bir defter olarak bulunur.

Bir gap ile bir yeniden sıralanma birkaç milisaniye aynı görünür

İkisi de aynı şekilde başlar: bir sonraki güncelleme beklediğiniz numarayı taşımaz. Fark zamandır; bu yüzden sınıflandırma geliş anında değil, sınırlı bir bekleme süresi dolduğunda yapılır.

  • Sırasızlık: N beklediniz, N+2 geldi ve bekleme hâlâ açıkken N+1 de geldi. Eksik bir şey yok, tek maliyet bekleme
  • Yineleme ya da yeniden iletim: en son uygulanana eşit ya da ondan küçük bir numara. Deftere dokunulmadan düşürülür ve sayılır; çünkü yükselen bir yineleme oranı yol hakkında bir şey söyler
  • Gap: bekleme süresi doldu ve N+1 hiç gelmedi. Defter deliğin ötesine ilerleyemez ve bu enstrüman kurtarmaya gider
  • Bayat: doğru numara, işe yarayamayacak kadar geç. Baytlar geldi, aşağı akış için bu bir kayıptır

Bozulmanın sessizleşmesini tek bir kural engeller: bir güncelleme yalnızca sıra numarası tam beklenen numaraysa uygulanır. Geri kalan her şey bekleme tamponuna ya da kurtarmaya gider. Sırasız bir delta'yı kabul eden bir defter fiyat vermeye devam eder ve sağlıklı görünür - borsayla arasındaki uyuşmazlık sonradan, bir istemci tarafından, anlamsız gelen bir gerçekleşmede bulunur.

Bekleme, büyüyen bir kuyruk değil, sınırlı bir yapıdır. Beklenen numaranın ilerisindeki güncellemeleri sıra numarasına göre anahtarlanmış biçimde tutar; böylece serbest bırakmak sıralama değil, arama işidir.

  • Serbest bırakma bir döngüdür: beklenen numarayı uygulayın, sonra numaralar ardışık kaldığı sürece tamponda hazır bekleyenleri uygulayın
  • Süre sınırı yalnızca bekleyen güncelleme sayısıyla değil, zamanla ifade edilir - ani yük, sayıya dayalı bir pencereyi tasarımın öngördüğünden çok daha erken doldurur
  • Tampon ne kadar beklerse, her tüketici o kadar bekler. Süre sınırını, güvenli hissettiren bir sayıdan değil, kendi yolunuzda ölçülen sıra bozulmasından çıkarın
  • Tampon taşması kendi başına bir gap ilanıdır: bekleme yalnızca zamanda değil, bellekte de sınırlıdır
  • Bekleme enstrüman ya da kanal başınadır, asla global değil. Sessiz tek bir enstrüman, etrafındaki her şeyi bekletmemelidir

Kurtarma, zaten tamponladığınız bir akışa eklenmiş bir snapshot'tır

İşin ters gittiği yer birleştirmedir. Snapshot, belli bir sıra numarası itibarıyla bir defterdir ve üretildiği anda bayattır; onu kullanılabilir kılan, o çekilirken tamponlanan artımlı akıştır.

  • Snapshot istenmeden önce artımlı akışı tamponlayın. Arkasında canlı bir akış olmayan bir snapshot, geldiği anda piyasanın çoktan gerisindedir
  • Snapshot'ın tutarlı olduğu sıra numarasını okuyun. Besleme böyle bir numara yayımlamıyorsa, o besleme pratikte yalnızca snapshot'a dayalıdır ve tasarımın bunu açıkça söylemesi gerekir
  • Snapshot sıra numarasına eşit ya da ondan küçük tamponlanmış güncellemeleri atın, kalanını sırayla uygulayın. Bunların ilki snapshot'tan hemen sonraki güncelleme değilse birleştirme başarısızdır ve kurtarma yeniden başlar
  • Snapshot gelmeden tampon dolarsa, bir kısmını uygulamak yerine kurtarmayı yeniden başlatın - kısmen uygulanmış bir kurtarma, sağlıklı bir defterden ayırt edilemez
  • Kurtarma sürerken enstrümanı, akışta açık bir durum olarak bozulmuş (degraded) yayımlayın. İçinde delik olan bir defteri güncel diye sunmak, defter hiç olmamasından kötüdür
  • Birleştirmeden sonra doğrulayın: besleme yayımlıyorsa yayımladığı checksum ya da sizin işlediğiniz defterle bir sonraki snapshot arasındaki uyum

Kurtarma bir arıza değil, normal bir olaydır ve maliyeti kapasite planına aittir: bir snapshot'ın çekilmesi ne kadar sürer, bu sırada ne kadar akış tamponlanır ve snapshot servisi darboğaza dönüşmeden aynı anda kaç enstrüman kurtarılabilir.

Fan-out: bir kez normalize et, bir kez kodla, çoğa gönder

Yüzlerce terminal oturumu aynı defteri ister. Ani yük altında katlanarak büyüyen hata, doğası gereği oturum başına olmayan işi oturum başına yapmaktır: her abone için defteri yeniden kurmak ya da aynı güncellemeyi her soket için ayrı ayrı serileştirmek.

  • Defterin sahibi, enstrüman shard'ı başına tek bir yazıcıdır. Okuyucular defteri asla değiştirmez; bu da hem kilidi hem de hangi sürümün yetkili olduğu sorusunu ortadan kaldırır
  • Yazıcı, sürümlenmiş güncellemeleri okuyucuların kendi hızlarında izlediği bir ring buffer'a yayımlar; böylece geride kalan bir okuyucu kimseyi yavaşlatmaz
  • Her güncelleme, her wire format için bir kez kodlanır ve oturumlar arasında referansla paylaşılır. Oturum başına olan yalnızca çerçeveleme ve akış denetimidir
  • Her oturum kendi giden sıra numarasını taşır; böylece istemci, yukarı akıştaki besleme hakkında hiçbir şey bilmeden kendi kayıplarını tespit edebilir
  • Sıralama enstrüman başına garanti edilir, çünkü istemcilerin dayandığı garanti budur. Enstrümanlar arası sıralama ya açıkça vaat edilip uygulanır ya da hiç vaat edilmez
  • Tek bir sürecin ötesinde fan-out bir röle katmanına dönüşür: her röle yukarı akıştan tek bir abonelik alır ve oturumların bir bölümüne hizmet eder; böylece yazıcının işi sabit kalır

Fan-out maliyetini, güncellemeyi kaç soketin aldığı değil, güncellemenin kaç kez dönüştürüldüğü belirler. Bir kez kodlayıp referans geçirmek oturum sayısıyla ölçeklenir; oturum başına defter yeniden kurmak ölçeklenmez.

Yavaş tüketici, başınıza gelen bir kaza değil, seçtiğiniz bir politikadır

Bir yerlerde kötü bir ağdaki bir oturum ya da render döngüsü takılmış bir terminal vardır ve giden tamponu dolar. Dört olası davranış vardır ve bunların ikisi yalnızca kazara seçilir.

  • Yavaş oturum boşalana kadar yazıcıyı bloke etmek: asla. Tek bir kötü bağlantıyı, o shard'daki herkes için bir latency olayına çevirir
  • Kuyruğu sınırsız büyütmek: yavaş bir tüketici bellek tükenmesine, ardından asıl oturumla ilgisi olmayan bir kesintiye dönüşür
  • Conflation'lı sınırlı kuyruk: istemcinin her ara adımı değil güncel resmi istediği defter durumu için doğru
  • High watermark'ta bağlantıyı kesen sınırlı kuyruk: conflate edilemeyen, bir kalemi düşürmenin anlamı düşürmek olduğu akışlar için doğru
  • Politika ne olursa olsun kuyruk oturum başınadır ve gecikme sürekli ölçülür - kuyruk derinliği ve yayımlanan sıra numarası ile sokete yazılan sıra numarası arasındaki mesafe
  • Bağlantı kopması nedenini bildirir. Açıklanmayan bir kapanış döngü içinde yeniden denenir; açıklanan bir kapanışın ardından yeniden abone olunur

İki taraf back pressure'da buluşur. Giden yol, defteri yazan tarafa geri baskı uygulayabiliyorsa, yavaş bir terminal sonunda beslemenin deftere işlenmesini geciktirir ve gap tespiti borsayla hiç ilgisi olmayan nedenlerle ötmeye başlar. İkisinin arasındaki sınırlı bir ring bu zinciri keser.

Conflation durum için dürüst, olaylar için yanlıştır

Defter bir durumdur: istemci güncel seviyeleri ister ve zaten değiştirilmiş bir değerin kendi başına anlamı yoktur. Trade tape ise bir olay günlüğüdür; oradaki her kalem gerçekleşmiş bir olgudur ve özetlenip atılamaz.

  • Conflate edilir: fiyat seviyesi güncellemeleri, top of book, toplulaştırılmış derinlik ve son fiyat ya da seans hacmi gibi türetilmiş istatistikler
  • Conflate edilmez: işlemler ve print'ler, emir ve gerçekleşme raporları, açık artırma ve seans faz değişiklikleri ve istemcinin zaman içinde topladığı her şey - conflate edilmiş bir akıştan kurulan bir tape, kendinden emin biçimde savunulan yanlış bir sayıdır
  • Akış başına değil, anahtar başına conflate edin. Her fiyat seviyesi için en son güncellemeyi tutmak defteri korur; genelde yalnızca en son güncellemeyi tutmak, en son değişmemiş her seviyeyi atar
  • Conflate edilmiş bir güncelleme, temsil ettiği durumun sıra numarasını taşır; böylece istemci hangi noktaya karşılık geldiğini bilir
  • Conflation aralığı, raporladığınız latency'nin bir parçasıdır. Bir aralıkta conflate edilen bir akış, conflate edilmemiş akışta ölçülen latency ile tarif edilmez
  • Her ara duruma ihtiyaç duyan bir istemci - bir backtest, bir uyum kaydı - conflate edilmemiş akışı alır ve bedelini bant genişliğiyle öder

Conflation bir sıkıştırma ayarı değil, bir biçim değişikliğidir. Bir akış bir kez conflate edildiğinde istemci iki güncelleme arasında ne olduğunu yeniden kuramaz ve ona akışın eksiksiz olduğu söylenmemelidir. İkisini birden yayımlamak - conflate edilmiş bir defter akışı ve conflate edilmemiş bir olay akışı - her iki istemci türünü de doğru tutan şeydir.

Yeniden bağlanma bir yeniden senkronizasyondur ve hepsi aynı anda gelir

Bir oturum geri döndüğünde, sunucu sürekliliği kanıtlayamıyorsa elindeki defter değersizdir. Varsayılan, abonelik başına sıra numarasıyla birlikte yeni bir snapshot'tır ve bu, önce yerel durumunu atmış bir istemciye uygulanır.

  • Sıra numarasından devam etme, yalnızca sınırlı bir replay tamponu varsa sunulur. İstenen numara pencereden düştüyse sunucu bunu söyler ve delikli bir akış göndermek yerine snapshot'a geri döner
  • Yeniden bağlanmada oturum durumu açık bir karardır: ya sunucu abonelikleri bir oturum jetonu altında sınırlı bir süre saklar ya da istemci bağlanırken hepsini yeniden bildirir. İkisi de çalışır; örtük bir karışım çalışmaz
  • Devam ettikten sonra yinelenen teslim beklenen bir şeydir ve istemci sıra numarasına bakarak atar. En az bir kez teslim artı sıra numaralandırma, tam olarak bir kez teslimden daha doğru uygulanır
  • Yeniden bağlanmalar birlikte gelir, çünkü bir oturumun bağlantısını kesen şey genelde birçoğunun bağlantısını kesmiştir. İstemcide jitter'lı backoff ve sunucuda kabul denetimi, kurtarmanın ikinci bir kesintiye dönüşmesini engeller
  • O kalabalık için snapshot'lar, belirli aralıklarla tazelenen enstrüman başına bir önbellekten gelir; böylece yazıcı, yeniden bağlanan her oturum için değil, bir takvime göre snapshot serileştirir
  • İstemci tarafındaki defter yamanmaz, yeniden kurulur. Eski seviyelerini saklayıp üstüne yeni delta'ları uygulayan bir terminal, bağlantı kopmadan önceki hatayı artık taze görünen bir deftere taşır

Tasarım yapmaya değer arıza tek bir yeniden bağlanma değildir. Yüzlerce oturumu aynı saniye içinde geri getiren, her birinin izlediği her enstrüman için snapshot istediği ve bu sırada alım tarafının aynı olayın ürettiği gap'ten kurtulduğu bir ağ olayıdır.

amBrain'in kamuya kanıtlayabildikleri: Erivan, Ermenistan'dan Rust ile low latency trading platformları, matching engine'ler ve real-time bidding sistemleri kuruyoruz ve yayımladığımız piyasa verisi latency'si - 5 ms altında - kurduğumuz yollarda ölçülüyor. Handler'ınız ani yük altında sıra numarası kaybediyorsa, konuşmaya değer konu, ikisinden biri yeniden yazılmadan önce alım tarafını dağıtım tarafından ayıran konuşmadır.

Masada buna benzer bir tasarım mı var?

Mevcut mimarinizi ve sizi endişelendiren hata senaryosunu getirin; yarım saatte birlikte üzerinden geçelim.

İlgili Yazılar

Görsel yüklenemedi
FinTech
Sep 9, 202610 dk okuma

Mühendis İşe Almak mı, Teknik Ortak mı: İki Yolun Maliyeti Nasıl Çıkarılır

Yazıyı oku
Görsel yüklenemedi
FinTech
Sep 8, 20269 dk okuma

Rust'ta Matching Engine Tasarımı: GC Duraklamaları Olmadan Price-Time Priority

Yazıyı oku
Görsel yüklenemedi
FinTech
Sep 8, 20268 dk okuma

Emir Yolunun İçinde İşlem Öncesi Risk Kontrolleri

Yazıyı oku