Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

การสร้างแพลตฟอร์มการซื้อขายตามเวลาจริงด้วย Redis

พอร์ตโฟลิโอเป็นรากฐานของอุตสาหกรรมการจัดการความมั่งคั่งและสินทรัพย์ นับตั้งแต่ Harry Makowitz เป็นผู้บุกเบิกทฤษฎีพอร์ตโฟลิโอสมัยใหม่ ผู้เชี่ยวชาญด้านการจัดการสินทรัพย์และความมั่งคั่งได้หมกมุ่นอยู่กับการเพิ่มผลตอบแทนจากพอร์ตโฟลิโอให้ได้มากที่สุดสำหรับระดับความเสี่ยงที่กำหนด ทุกวันนี้ ผู้เชี่ยวชาญในอุตสาหกรรมนี้มีนักลงทุนรายย่อยหลายล้านคนเข้าร่วม ซึ่งได้เปลี่ยนแนวการลงทุนไปตลอดกาล ผู้เข้าร่วมรายใหม่เหล่านี้กำลังสร้างการแตกสาขาขนาดใหญ่สำหรับเทคโนโลยีที่สนับสนุนโครงสร้างพื้นฐานการซื้อขายของนายหน้าค้าปลีก การแลกเปลี่ยน และสำนักหักบัญชี

ยกตัวอย่างเช่น ความคลั่งไคล้หุ้น GameStop ในเดือนมกราคม 2021 นักลงทุนรายย่อยเริ่มซื้อขายหุ้น GameStop ที่ระดับสูงสุดเป็นประวัติการณ์ นักลงทุนเหล่านี้ยังสะสมหุ้นมีมอื่นๆ เช่น AMC Entertainment ทำให้ความผันผวนของตลาดโดยรวมเพิ่มขึ้นมากกว่า 76% ในเวลาเพียงไม่กี่วันทำการตามที่วัดโดย VIX ความผันผวนนี้นำไปสู่แรงกดดันด้านราคาหลักทรัพย์หลายพันตัว นักลงทุนหลายล้านคนพยายามเข้าถึงพอร์ตโฟลิโอของพวกเขาอย่างบ้าคลั่งพร้อมๆ กัน แต่ต้องเผชิญกับแอปที่ไม่สามารถตอบสนองความต้องการได้ นักลงทุนไม่ใจดีกับบริษัทที่แอปทำงานได้ไม่ดีในเวลาที่ต้องการมากที่สุด

การสร้างแพลตฟอร์มการซื้อขายตามเวลาจริงด้วย Redis

ในช่วงเวลาอันวุ่นวายนี้ นักลงทุนส่วนใหญ่กำลังมองหาจุดข้อมูลสองจุดเกี่ยวกับพอร์ตโฟลิโอที่พวกเขาต้องการเข้าถึงตลอดเวลา:

  1. มูลค่ารวมของพอร์ตโฟลิโอในขณะนั้นคือเท่าไร
  2. กำไรหรือขาดทุนของหลักทรัพย์เฉพาะในพอร์ตการลงทุนมีอะไรบ้าง

คำตอบสำหรับคำถามเหล่านี้อาจทำให้นักลงทุนซื้อ ขาย หรือถือหลักทรัพย์เฉพาะได้ ในตลาดที่เคลื่อนไหวอย่างรวดเร็วในปัจจุบัน ความล่าช้าใดๆ อาจหมายถึงการสูญเสียโอกาสและผลกำไร คุณต้องเข้าถึงราคาแบบเรียลไทม์เพื่อตอบคำถามเหล่านี้ แต่มีความท้าทายใหญ่ 2 ประการ:

  • อัพเดทราคาหลักทรัพย์นับพันพร้อมกัน
  • ตอบรับคำขอของลูกค้านับล้านพร้อมกัน

ราคาของหลักทรัพย์สามารถเปลี่ยนแปลงได้อย่างรวดเร็วตามปริมาณการซื้อขาย ความผันผวนของหลักทรัพย์เฉพาะ และความผันผวนในตลาด ในทางกลับกัน นายหน้าอาจมีลูกค้าหลายล้านราย แต่ละคนมีหลักทรัพย์สองสามโหลในพอร์ตของพวกเขา ทันทีที่ลูกค้าเข้าสู่ระบบ พอร์ตโฟลิโอของพวกเขาจะต้องได้รับการอัปเดตด้วยราคาล่าสุด—และคอยอัปเดตอยู่เสมอเมื่อนายหน้าได้รับราคาจากการแลกเปลี่ยน

โดยพื้นฐานแล้ว เรากำลังสร้างแผนภูมิหุ้นแบบเรียลไทม์ แอปนายหน้าจำนวนมากไม่พยายามทำสิ่งนี้ในวงกว้าง แอปเหล่านี้ดึงราคาล่าสุดแทนที่จะผลักดันราคาให้แก่ลูกค้าหลายล้านราย ตัวอย่างเช่น อาจมีปุ่มรีเฟรชในหน้าพอร์ตโฟลิโอ

ความท้าทายรุ่นต่อไปเหล่านี้ไม่ใช่เรื่องเล็กน้อยและไม่สามารถแก้ไขได้ง่ายๆ ด้วยฐานข้อมูลบนดิสก์ ซึ่งไม่ได้ออกแบบมาเพื่อรองรับการดำเนินการหลายล้านรายการต่อวินาที ข้อกำหนดของอุตสาหกรรมการเงินจำเป็นต้องมีฐานข้อมูลที่สามารถปรับขนาดได้อย่างง่ายดายและจัดการการดำเนินการหลายร้อยล้านรายการในแต่ละวินาที ในอีกไม่นาน Redis Enterprise ซึ่งเป็นแพลตฟอร์มฐานข้อมูลในหน่วยความจำมีศักยภาพที่จะจัดการกับความท้าทายมากมายเหล่านี้

การสร้างแพลตฟอร์มการซื้อขายตามเวลาจริงด้วย Redis

นี่เป็นชุดแรกของบล็อกที่ครอบคลุมกรณีการใช้งานแบบเรียลไทม์ต่างๆ ในโลกการเงิน เราจะกล่าวถึงรายละเอียดและความท้าทายทางธุรกิจของกรณีการใช้งานแต่ละกรณี และบทบาทของ Redis Enterprise ในการแก้ปัญหาความท้าทายเหล่านั้น ในบล็อกนี้ เราขอเสนอการออกแบบตัวอย่าง โมเดลข้อมูล และตัวอย่างโค้ด เราจะหารือเกี่ยวกับข้อดีและข้อเสียของแต่ละวิธี

ในบล็อกโพสต์นี้ เราจะกล่าวถึงสิ่งต่อไปนี้:

  • ตัวอย่างการใช้งานโมเดลข้อมูลพอร์ตหลักทรัพย์ที่มีประสิทธิภาพสูงและสามารถปรับขนาดได้บน Redis Enterprise
  • อัพเดทราคาหลักทรัพย์ในพอร์ตแบบเรียลไทม์เนื่องจากนายหน้ารับราคาล่าสุดจากการแลกเปลี่ยน

เมื่อแอพไคลเอนต์ดึงพอร์ตโฟลิโอและได้รับราคาล่าสุดแล้ว ก็สามารถ:

  • คำนวณมูลค่าพอร์ตโฟลิโอรวมของพอร์ตโฟลิโอ
  • คำนวณกำไรหรือขาดทุนจากการถือพอร์ตแต่ละพอร์ต

รูปแบบข้อมูลพอร์ตโฟลิโอหลักทรัพย์

เริ่มต้นด้วยการสร้างแบบจำลองการถือครองในพอร์ตโฟลิโอ ในภาพประกอบด้านล่าง CVS Health Corp. (NYSE: CVS) เป็นหนึ่งในตัวอย่างการถือครองของเรา มี CVS แยกกัน 2 ล็อต โดยครั้งแรกได้มาเมื่อวันที่ 4 มกราคม 2021 และครั้งที่สองในวันที่ 1 มีนาคม 2021 มีการซื้อหุ้นจำนวนเท่ากันระหว่างซื้อ   ซื้อขายแต่ละล็อต การซื้อขายทั้งสองมีไว้สำหรับ 10 หุ้น อย่างไรก็ตาม ราคาต่อหุ้น —68.3378 ดอลลาร์สำหรับล็อตแรกและ 68.82 ดอลลาร์สำหรับล็อตที่สอง ปริมาณรวมของ CVS ที่ถืออยู่ในพอร์ตโฟลิโอคือ 20 โดยมีต้นทุนเฉลี่ยคำนวณดังนี้ (($68.3378 * 10) + ($68.82 * 10))/20 =$68.5789 ต่อหุ้น

การสร้างแพลตฟอร์มการซื้อขายตามเวลาจริงด้วย Redis

การปฏิบัติตามข้อกำหนด

การสร้างแพลตฟอร์มการซื้อขายตามเวลาจริงด้วย Redis

การแสดงข้อมูลของ Redis เป็นแบบแบน ไม่สามารถฝังชุดได้ ตัวอย่างเช่น ภายในชุดอื่น ดังนั้นแบบจำลองข้อมูลตามที่อธิบายไว้ในไดอะแกรม ER จึงไม่สามารถนำมาใช้โดยตรงได้ การใช้โมเดลเอนทิตีโดยตรงอาจไม่มีลักษณะประสิทธิภาพที่ต้องการ ดังนั้นคุณจะต้องคิดให้แตกต่างออกไปเล็กน้อยเมื่อคุณเริ่มใช้งาน ในส่วนนี้ เราจะกล่าวถึงหลักการออกแบบพื้นฐานบางอย่างที่จำเป็นเมื่อออกแบบการใช้งานที่มีประสิทธิภาพสูงและการปรับขนาดโดยใช้ Redis

โมเดลข้อมูลกล่าวถึงเอนทิตีต่อไปนี้:

การสร้างแพลตฟอร์มการซื้อขายตามเวลาจริงด้วย Redis

ไดอะแกรม ER แสดงภาพซึ่งสามารถช่วยให้เราเห็นว่าเกิดอะไรขึ้น

สิ่งที่ขาดหายไปจากแผนภาพด้านบนคือชุดของราคาที่เข้ามา แม้ว่าจะถูกบันทึกไว้ในประวัติราคาของหลักทรัพย์—และการคำนวณ มูลค่าและกำไรที่เกิดขึ้นทันที เมื่อราคาเปลี่ยนแปลง ดังนั้น ไดอะแกรม ER จะแสดงข้อมูลที่ค่อนข้างคงที่ซึ่งเป็นบริบทในการประเมินพอร์ตโฟลิโอ

สถาปัตยกรรมโดยรวม

ประเด็นสำคัญที่ต้องพิจารณาเกี่ยวกับระบบนี้ ได้แก่:

  • ความทันเวลา (เช่น เวลาในการตอบสนอง) เป็นสิ่งสำคัญ นี่คือคุณสมบัติในการขับขี่โดยรวม
  • การคำนวณมูลค่าพอร์ตจะรวมข้อมูลเฉพาะบัญชี (เช่น ข้อมูลล็อต) กับข้อมูลที่แชร์ระหว่างบัญชี (เช่น ราคาความปลอดภัย) ข้อมูลเฉพาะบัญชีจึงเป็นบริบทที่ใช้ข้อมูลร่วมกัน
  • มูลค่าพอร์ตโฟลิโอจะต้องคำนวณสำหรับบัญชีที่นักลงทุนออนไลน์เท่านั้น (เศษเสี้ยวของจำนวนบัญชีทั้งหมด)
  • ข้อมูลไหลผ่านระบบ จากการแลกเปลี่ยนที่มีการผลิตราคาออกไปยังเครื่องของลูกค้า (เบราว์เซอร์ แอปพลิเคชันโทรศัพท์มือถือ) ที่นำเสนอมูลค่าพอร์ตต่อนักลงทุนออนไลน์
  • พื้นที่เฉพาะที่มีไดนามิกในระดับสูง ได้แก่ อัตราการไหลของข้อมูลเข้าและจำนวนนักลงทุนออนไลน์

จากประเด็นเหล่านี้ วิธีการทั่วไปมีดังนี้:

  • อาศัยสถาปัตยกรรมในหน่วยความจำของ Redis สำหรับการเข้าถึงข้อมูลแบบสแตติกและไดนามิกที่มีเวลาแฝงต่ำ
  • เพิ่มประสิทธิภาพการสร้างแบบจำลองข้อมูลโดยใช้โครงสร้างข้อมูลของ Redis เพื่อให้เข้าถึงข้อมูลบริบทที่เปลี่ยนแปลงช้าได้อย่างรวดเร็ว
  • การใช้โครงสร้างการสื่อสารของ Redis (สตรีม กลุ่มผู้บริโภค Pub/Sub) เพื่อจัดการข้อกำหนดข้อมูลแบบไดนามิก
  • ลดการจัดเก็บข้อมูลให้เหลือเฉพาะที่จำเป็นโดยไม่กระทบต่อประสิทธิภาพโดยรวมของระบบ
  • การนำการคำนวณเฉพาะลูกค้าไปใช้กับตัวลูกค้าเอง สิ่งนี้จะปรับขนาดตามธรรมชาติและโดยอัตโนมัติตามจำนวนนักลงทุนออนไลน์ ซึ่งช่วยบรรเทาภาระจากขนาดได้อย่างมาก

นี่คือองค์ประกอบการคำนวณที่สำคัญและการไหลของข้อมูล:

การสร้างแพลตฟอร์มการซื้อขายตามเวลาจริงด้วย Redis

โปรดทราบว่า Redis Enterprise ประกอบด้วยโหนดอย่างน้อยหนึ่งโหนดในเครื่องจำนวนมาก—ปรับใช้ในสถานที่, Kubernetes, การปรับใช้คลาวด์แบบไฮบริด, บริการที่มีการจัดการ หรือบริการคลาวด์ของบุคคลที่หนึ่งดั้งเดิม—และจะมีนักลงทุนหลายแสนคนออนไลน์กับลูกค้าของพวกเขา ) ทางเลือก

ส่วนประกอบของ Redis Enterprise

การอัปเดตราคาความปลอดภัยจะถูกดูดซับโดย Redis Streams การอัปเดตสำหรับหลักทรัพย์จะถูกผสมเข้าด้วยกันในสตรีมนี้ และจะต้องแยกส่วนเพื่อให้ข้อมูลมีประโยชน์ กลุ่มผู้บริโภคจะใช้เพื่อดำเนินการแยกส่วนนั้น และประมวลผลข้อมูลออกเป็นสองโครงสร้าง ต่อการรักษาความปลอดภัย:

  • ฐานข้อมูล RedisTimeSeries เพื่อติดตามประวัติการเปลี่ยนแปลงราคา (รวมถึงบันทึกราคาล่าสุดสำหรับลูกค้าที่เพิ่งเชื่อมต่อ)
  • ช่องโบรกเกอร์ Pub/Sub เพื่อส่งการแจ้งเตือนการเปลี่ยนแปลงราคาไปยังลูกค้าที่สมัครรับข้อมูลจากช่องนั้น (เช่น นักลงทุนที่มีพอร์ตโฟลิโอรวมถึงการรักษาความปลอดภัยนั้น)

ไดอะแกรมต่อไปนี้ให้รายละเอียดส่วนนี้ของสถาปัตยกรรม:

การสร้างแพลตฟอร์มการซื้อขายตามเวลาจริงด้วย Redis

ปัจจัยที่สำคัญที่สุดในรูปแบบของเราคือข้อมูลเฉพาะบัญชีที่แสดงถึงล็อตและการรักษาความปลอดภัยที่เกี่ยวข้อง เราจะเปรียบเทียบการใช้งานทั้งสองแบบเป็นตัวอย่างของการคิดเกี่ยวกับการสร้างแบบจำลองข้อมูลใน Redis โดยเน้นที่ประสิทธิภาพ การใช้งานอื่นๆ เป็นไปได้ เป้าหมายของเราคือการแนะนำหลักการออกแบบโดยรวมและกระบวนการคิดเมื่อนำข้อมูลไปใช้ใน Redis

เราจะใช้ข้อมูลต่อไปนี้เป็นตัวอย่างที่เป็นรูปธรรม:

การสร้างแพลตฟอร์มการซื้อขายตามเวลาจริงด้วย Redis

เรากำลังกำหนดราคาในสกุลเงินที่ต่ำที่สุดเท่าที่จะเป็นไปได้เพื่อหลีกเลี่ยงการลอยตัวและเก็บทุกอย่างเป็นจำนวนเต็ม เราสามารถอนุญาตให้ลูกค้าจัดการกับการเปลี่ยนแปลงเป็นดอลลาร์และเซ็นต์ ในตัวอย่างนี้ เรากำลังใช้ราคาที่มีทศนิยมสองตำแหน่งที่แม่นยำ

โมเดลข้อมูล A

การใช้งานครั้งแรกของเราบันทึกรหัสของล็อตทั้งหมดในบัญชีโดยใช้ SET ซึ่งระบุด้วยรหัสบัญชี จากนั้นใช้ Redis HASH หนึ่งรายการต่อ LOT ซึ่งระบุโดย LOT ID โดยมีสัญลักษณ์ ปริมาณ และราคาซื้อเป็นฟิลด์ กล่าวคือ เรากำลังใช้ HASH เพื่อสร้างแบบจำลองโครงสร้างเอนทิตี LOT ด้วยแอตทริบิวต์แต่ละรายการ ของเอนทิตี LOT ที่เป็นฟิลด์ ใน Redis HASH

ด้วยโมเดลข้อมูลนี้ เรามีคีย์สำหรับแต่ละบัญชีและค่าที่มี LOT ID ทั้งหมดสำหรับบัญชีนั้นที่จัดเก็บเป็น Redis SET:

lotids:<ACCOUNT_ID> SET <LOTID>

นอกจากนี้ สำหรับแต่ละ lotid เราจะมี HASH ที่มีฟิลด์เป็นทิกเกอร์ ปริมาณ และราคาซื้อ:

lot:<LOTID> HASH <ticker TICKER> <quantity INTEGER> <price INTEGER>

เราจะสร้างคีย์ในลักษณะนี้:

127.0.0.1:6379> SADD lotids:ACC-1001 LOT-9001 LOT-9002
(integer) 2
127.0.0.1:6379> HMSET lot:LOT-9001 ticker AAPL quantity 200 price 12556
OK
127.0.0.1:6379> HMSET lot:LOT-9002 ticker CAT quantity 1200 price 18063
OK

โมดูล RedisTimeSeries ช่วยให้สามารถจัดเก็บและดึงข้อมูลคู่ของเวลาและค่าที่เกี่ยวข้อง พร้อมกับการแทรกปริมาณสูงและการอ่านที่มีความหน่วงต่ำ เรากำลังจะได้รับราคาล่าสุดสำหรับทิกเกอร์ที่สนใจซึ่งลูกค้าจะเข้าถึงได้เมื่อใช้คีย์อนุกรมเวลาที่เกี่ยวข้อง:

price_history:<TICKER> TIMESERIES <price INTEGER>

127.0.0.1:6379> TS.GET price_history:APPL
1) (integer) 1619456853061
2) 12572
127.0.0.1:6379> TS.GET price_history:CAT
1) (integer) 1619456854120
2) 18021

และติดตามช่องราคาเพื่อรับข้อมูลอัปเดต:

<TICKER> SUBSCRIPTION_CHANNEL

ในการรับข้อมูลทั้งหมด ลูกค้าจะดำเนินการดังต่อไปนี้:

  1. 1 ครั้ง SMEMBERS บน lotids คีย์—ความซับซ้อนของเวลา O(N) โดยที่ N เป็นจำนวนล็อต
  2. N ครั้ง HGETALL บน ล็อต คีย์—ความซับซ้อนของเวลา N คูณ O(1)
  3. T คูณ TS.GET ใน price_history คีย์ – ความซับซ้อนของเวลา T คูณ O(1) โดยที่ T เป็นจำนวนทิกเกอร์
  4. สมัครสมาชิก 1 ครั้งบน  ช่อง – ความซับซ้อนของเวลา O(T) (สามารถสมัครรับข้อมูลทุกช่องในการโทรครั้งเดียวเพื่อ SUBSCRIBE)

ความซับซ้อนของเวลาโดยรวมคือ O(N +T)

อย่างเป็นรูปธรรม การดำเนินการที่หนึ่งและสองจะเป็น:

127.0.0.1:6379> SMEMBERS lotids:ACC1001
1) "LOT-9001"
2) "LOT-9002"
127.0.0.1:6379> HGETALL lot:LOT-9001
1) "ticker"
2) "AAPL"
3) "quantity"
4) "200"
5) "price"
6) "12556"
127.0.0.1:6379> HGETALL lot:LOT-9002
1) "ticker"
2) "CAT"
3) "quantity"
4) "1200"
5) "price"
6) "18063"

เราสามารถลดเวลาแฝงของเครือข่ายได้โดยใช้การวางท่อ (รูปแบบของการแบทช์ในฝั่งไคลเอ็นต์) และ/หรือการใช้สคริปต์ LUA ซ้ำๆ (โดยใช้ SCRIPT LOAD & EVALSHA) หมายเหตุด้านข้าง:ธุรกรรมสามารถใช้งานได้โดยใช้ไปป์ไลน์และให้เวลาในการตอบสนองของเครือข่ายลดลง แต่นี่เป็นข้อมูลเฉพาะไคลเอ็นต์และเป้าหมายของธุรกรรมคืออะตอมมิกบนเซิร์ฟเวอร์ จึงไม่แก้ปัญหาเวลาในการตอบสนองของเครือข่ายได้จริงๆ ไปป์ไลน์ประกอบด้วยคำสั่งที่อินพุตและเอาต์พุตต้องเป็นอิสระจากกัน สคริปต์ LUA กำหนดให้ต้องระบุคีย์ทั้งหมดล่วงหน้า และ ว่าคีย์ทั้งหมดถูกแฮชไปยังสล็อตเดียวกัน (ดูเอกสาร Redis Enterprise ในหัวข้อนี้สำหรับรายละเอียดเพิ่มเติม)

จากข้อจำกัดเหล่านี้ เราจะเห็นได้ว่าการกำหนดการดำเนินการให้กับไปป์ไลน์คือ:

  • ไปป์ไลน์ 1:คำสั่งเดียวของการทำงาน #1
  • ไปป์ไลน์ 2:คำสั่ง N ทั้งหมดของการทำงาน #2
  • ไปป์ไลน์ 3:คำสั่ง N ทั้งหมดของการดำเนินการ #3 และ #4

และใช้สคริปต์ LUA ไม่ได้ เนื่องจากการดำเนินการแต่ละครั้งใช้คีย์ต่างกัน และคีย์เหล่านั้นไม่มีส่วนร่วมที่สามารถแฮชลงในช่องเดียวกันได้

ในการใช้โมเดลนี้ เรามีความซับซ้อนด้านเวลาของ O(N+T) และการกระโดดของเครือข่าย 3 ครั้ง

โมเดลข้อมูล B

อีกรูปแบบหนึ่งคือทำให้โครงสร้างเอนทิตี LOT แบนราบ และแสดงแอตทริบิวต์เอนทิตีแต่ละรายการโดยใช้คีย์ที่ระบุโดยรหัสบัญชี—หนึ่งคีย์ดังกล่าวสำหรับแต่ละแอตทริบิวต์ (ปริมาณ เครื่องหมาย ราคา) ของล็อต ฟิลด์ในแต่ละ HASH จะเป็น LOT ID และค่าที่สอดคล้องกับปริมาณ สัญลักษณ์ หรือราคา ดังนั้นเราจึงมีกุญแจ:

tickers_by_lot: <ACCOUNT_ID> HASH <LOTID TICKER>

quantities_by_lot:<ACCOUNT_ID> HASH <LOTID INTEGER>

prices_by_lot:<ACCOUNT_ID> HASH <LOTID INTEGER>

แฮชเหล่านี้จะแทนที่คีย์ LOTID และ LOT จาก Data Model A ในขณะที่ price_history และ <TICKER> กุญแจจะยังคงเหมือนเดิม

การสร้างคีย์:

HSET tickers_by_lot:ACC-1001 LOT-9001 AAPL LOT-9002 CAT
HSET quantities_by_lot:ACC-1001 LOT-9001 200 LOT-9002 1200
HSET prices_by_lot:ACC-1001 LOT-9001 125.56 LOT-9002 180.63

กำลังดึงค่า:

127.0.0.1:6379> HGETALL tickers_by_lot:ACC-1001
1) "LOT-9001"
2) "AAPL"
3) "LOT-9002"
4) "CAT"
127.0.0.1:6379> HGETALL quantities_by_lot:ACC-1001
1) "LOT-9001"
2) "200"
3) "LOT-9002"
4) "1200"
127.0.0.1:6379> HGETALL prices_by_lot:ACC-1001
1) "LOT-9001"
2) "12556"
3) "LOT-9002"
4) "18063"

การดำเนินการที่ลูกค้าต้องการในตอนนี้คือ:

  1. 1 ครั้ง HGETALL ใน lot_quantity คีย์—ความซับซ้อนของเวลา N x O(1)
  2. 1 ครั้ง HGETALL ใน lot_ticker คีย์—ความซับซ้อนของเวลา N x O(1)
  3. 1 ครั้ง HGETALL ใน lot_price คีย์—ความซับซ้อนของเวลา N x O(1)
  4. T คูณ TS.GET ใน price_history คีย์—ความซับซ้อนของเวลา T x O(1) โดย T คือจำนวนทิกเกอร์
  5. 1 ครั้ง SUBSCRIBE บน ช่อง—ความซับซ้อนของเวลา 1 x O(T)

สิ่งนี้มีเวลาโดยรวมที่ซับซ้อนของ O(N+T)—เหมือนเดิม

จากมุมมองของไปป์ไลน์ สิ่งนี้จะกลายเป็น:

  • Pipeline one—คำสั่งการดำเนินการทั้งหมด #1, #2 และ  #3
  • ไปป์ไลน์ที่สอง—คำสั่ง T ทั้งหมดของการดำเนินการ #4 และ #5

ดังนั้นเราจึงลดจำนวนการกระโดดของเครือข่ายลงหนึ่ง—ไม่มากในแง่สัมบูรณ์ แต่ 33% ในแง่ที่สัมพันธ์กัน

นอกจากนี้ เราสามารถใช้ LUA ได้อย่างง่ายดายเนื่องจากเรารู้จักคีย์ และเราสามารถจับคู่คีย์ทั้งหมดสำหรับบัญชีใดบัญชีหนึ่งกับช่องเดียวกันได้ ด้วยความเรียบง่ายของการดำเนินการ เราจะไม่เจาะลึก LUA เพิ่มเติม แต่โปรดทราบว่าการออกแบบนี้ทำให้เป็นไปได้อย่างน้อย!

ในการวัดประสิทธิภาพอย่างง่าย Data Model B รันเร็วขึ้น 4.13 ms (เปรียบเทียบการทำงานกว่าพันครั้ง) เนื่องจากการดำเนินการนี้จะดำเนินการเพียงครั้งเดียวในแต่ละครั้งที่ลูกค้าเริ่มต้นสำหรับบัญชี การดำเนินการนี้จึงไม่มีผลกระทบต่อประสิทธิภาพโดยรวม

สรุป

ในบล็อกนี้ เราได้แสดงการใช้งานโมเดลเอนทิตีที่เป็นไปได้สองแบบโดยใช้ประเภทข้อมูล Redis เรายังได้แนะนำการวิเคราะห์ความซับซ้อนของเวลาที่ควรทำทุกครั้งที่เลือกประเภทข้อมูล Redis ควบคู่ไปกับการพิจารณาถึงการปรับปรุงประสิทธิภาพของเครือข่าย ซึ่งเป็นขั้นตอนที่สำคัญเมื่อต้องใช้ขนาดใหญ่และประสิทธิภาพสูง ในบล็อกต่อๆ มา เราจะขยายแนวคิดเหล่านี้เพิ่มเติมเมื่อมีการขยายแบบจำลองข้อมูล

เราได้นำเสนอความท้าทายทางธุรกิจบางประการในการจัดการพอร์ตหลักทรัพย์ตามขนาดและได้แสดงให้เห็นดังต่อไปนี้:

  • แบบจำลองข้อมูล Redis สำหรับการใช้งานพอร์ตหลักทรัพย์แบบเรียลไทม์และปรับขนาดได้
  • ระบบอัปเดตราคาแบบเรียลไทม์ประสิทธิภาพสูงที่สามารถใช้คำนวณมูลค่ารวมของพอร์ตโฟลิโอและกำไรหรือขาดทุนจากการถือครองแต่ละครั้ง

ด้วยคุณสมบัติที่สำคัญสองประการนี้ ลูกค้าแอพนายหน้าสามารถให้การอัปเดตพอร์ตแบบเรียลไทม์ที่ดำเนินการและปรับขนาดเพื่อจัดการบัญชีนับล้าน การออกแบบนี้สามารถแสดงมูลค่ารวมของพอร์ตโฟลิโอและกำไรหรือขาดทุนจากการถือครองแต่ละครั้งแบบเรียลไทม์ โมเดลข้อมูลและสถาปัตยกรรมนี้ยังสามารถนำไปใช้กับกรณีอื่นนอกเหนือจากหลักทรัพย์เพื่อครอบคลุมการเข้ารหัสลับ การแลกเปลี่ยนโฆษณา ฯลฯ