การเพิ่มประสิทธิภาพการโหลดในโครงการ Highload ด้วย ElasticSearch

เฮ้ ฮับ! ฉันชื่อ Maxim Vasiliev ฉันทำงานเป็นนักวิเคราะห์และผู้จัดการโครงการที่ FINCH วันนี้ฉันอยากจะบอกคุณว่าการใช้ ElasticSearch เราสามารถประมวลผลคำขอ 15 ล้านคำขอใน 6 นาทีและเพิ่มประสิทธิภาพการโหลดรายวันบนไซต์ของหนึ่งในลูกค้าของเราได้อย่างไร น่าเสียดายที่เราจะต้องดำเนินการโดยไม่มีชื่อ เนื่องจากเรามี NDA เราหวังว่าเนื้อหาของบทความจะไม่ได้รับผลกระทบจากสิ่งนี้ ไปกันเถอะ.

โครงการทำงานอย่างไร

ในแบ็กเอนด์ของเรา เราสร้างบริการที่รับประกันประสิทธิภาพของเว็บไซต์และแอปพลิเคชันบนมือถือของลูกค้าของเรา โครงสร้างทั่วไปสามารถดูได้ในแผนภาพ:

การเพิ่มประสิทธิภาพการโหลดในโครงการ Highload ด้วย ElasticSearch

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

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

พื้นหลังสั้น ๆ

เริ่มแรกเราใช้ PostgreSQL เป็นที่เก็บข้อมูลเพียงอย่างเดียว ข้อได้เปรียบมาตรฐานสำหรับ DBMS: การมีอยู่ของธุรกรรม, ภาษาตัวอย่างข้อมูลที่พัฒนาขึ้น, เครื่องมือที่หลากหลายสำหรับการรวม; ประกอบกับประสิทธิภาพที่ดีเป็นที่พึงพอใจของเรามาอย่างยาวนาน

เราจัดเก็บข้อมูลทั้งหมดไว้ใน Postgres ตั้งแต่ธุรกรรมไปจนถึงข่าวสาร แต่จำนวนผู้ใช้เพิ่มขึ้นและจำนวนคำขอก็เพิ่มขึ้นด้วย

เพื่อความเข้าใจ จำนวนเซสชันประจำปีในปี 2017 เฉพาะบนไซต์เดสก์ท็อปคือ 131 ล้าน ในปี 2018 - 125 ล้าน 2019 อีก 130 ล้าน เพิ่มอีก 100-200 ล้านจากไซต์เวอร์ชันมือถือและแอปพลิเคชันมือถือ และคุณ จะได้รับคำขอจำนวนมาก

ด้วยการเติบโตของโครงการ Postgres หยุดรับมือกับภาระงาน เราไม่มีเวลา - มีคำถามมากมายปรากฏขึ้นซึ่งเราไม่สามารถสร้างดัชนีได้เพียงพอ

เราเข้าใจดีว่าจำเป็นต้องมีที่เก็บข้อมูลอื่นๆ ที่จะตอบสนองความต้องการของเราและปลดภาระจาก PostgreSQL Elasticsearch และ MongoDB ถือเป็นตัวเลือกที่เป็นไปได้ หลังแพ้ในประเด็นต่อไปนี้:

  1. ความเร็วในการจัดทำดัชนีช้าลงเนื่องจากจำนวนข้อมูลในดัชนีเพิ่มขึ้น ด้วย Elastic ความเร็วไม่ได้ขึ้นอยู่กับปริมาณข้อมูล
  2. ไม่มีการค้นหาข้อความแบบเต็ม

ดังนั้นเราจึงเลือก Elastic สำหรับตัวเราเองและเตรียมพร้อมสำหรับการเปลี่ยนแปลง

เปลี่ยนเป็นยางยืด

1. เราเริ่มเปลี่ยนจากบริการค้นหาจุดขาย ลูกค้าของเรามีจุดขายทั้งหมดประมาณ 70 จุด ซึ่งต้องใช้การค้นหาหลายประเภทบนเว็บไซต์และในแอปพลิเคชัน:

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

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

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

3. จากนั้นเราย้ายการประมวลผลธุรกรรม ผู้ใช้สามารถซื้อผลิตภัณฑ์บางอย่างบนเว็บไซต์และเข้าร่วมการจับรางวัลได้ หลังจากการซื้อดังกล่าว เราจะประมวลผลข้อมูลจำนวนมาก โดยเฉพาะในวันหยุดสุดสัปดาห์และวันหยุด สำหรับการเปรียบเทียบ หากในวันธรรมดาจำนวนการซื้ออยู่ระหว่าง 1,5-2 ล้าน ตัวเลขดังกล่าวจะสูงถึง 53 ล้านในวันหยุด

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

การเป็นช่วง ๆ

ขณะนี้การอัปเดตได้รับการกำหนดค่าตามเหตุการณ์ตามเงื่อนไขต่อไปนี้:

  1. จุดขาย. ทันทีที่เราได้รับข้อมูลจากแหล่งภายนอก เราจะเริ่มการอัปเดตทันที
  2. ข่าว. ทันทีที่มีการแก้ไขข่าวสารบนเว็บไซต์ ข่าวนั้นจะถูกส่งไปยัง Elastic โดยอัตโนมัติ

เป็นอีกครั้งที่ควรค่าแก่การกล่าวถึงข้อดีของยางยืด ใน Postgres เมื่อส่งคำขอ คุณต้องรอจนกว่าระบบจะประมวลผลบันทึกทั้งหมดอย่างตรงไปตรงมา คุณสามารถส่งเรคคอร์ด 10 รายการไปยัง Elastic และเริ่มทำงานได้ทันที โดยไม่ต้องรอให้เรคคอร์ดถูกแจกจ่ายไปยัง Shards ทั้งหมด แน่นอนว่า Shard หรือ Replica บางอย่างอาจไม่เห็นข้อมูลทันที แต่ทุกอย่างจะพร้อมใช้งานเร็วๆ นี้

วิธีการบูรณาการ

มี 2 ​​วิธีในการรวมเข้ากับ Elastic:

  1. ผ่านไคลเอ็นต์ดั้งเดิมผ่าน TCP ไดรเวอร์เนทีฟกำลังค่อยๆ หมดลง: ไม่รองรับอีกต่อไป มีไวยากรณ์ที่ไม่สะดวกอย่างยิ่ง ดังนั้นเราจึงไม่ใช้มันจริงและพยายามละทิ้งมันโดยสิ้นเชิง
  2. ผ่านอินเทอร์เฟซ HTTP ที่ใช้ได้ทั้งคำขอ JSON และไวยากรณ์ของ Lucene อันสุดท้ายคือ text engine ที่ใช้ Elastic ในเวอร์ชันนี้ เราได้รับความสามารถในการแบทช์ผ่านคำขอ JSON ผ่าน HTTP นี่คือตัวเลือกที่เราพยายามใช้

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

ตัวเลขสำหรับการเปรียบเทียบ:

  • บันทึกผู้ใช้รางวัล Postgres ใน 20 เธรดโดยไม่ต้องจัดกลุ่ม: 460713 บันทึกใน 42 วินาที
  • ไคลเอ็นต์แบบยืดหยุ่น + แบบโต้ตอบสำหรับ 10 เธรด + ชุดสำหรับ 1000 องค์ประกอบ: 596749 บันทึกใน 11 วินาที
  • ไคลเอนต์ยืดหยุ่น + ปฏิกิริยาสำหรับ 10 เธรด + ชุดสำหรับ 1000 องค์ประกอบ: 23801684 รายการใน 4 นาที

ตอนนี้เราได้เขียนโปรแกรมจัดการคำขอ HTTP ที่สร้าง JSON เป็น Batch/not Batch แล้วส่งผ่านไคลเอ็นต์ HTTP ใดๆ โดยไม่คำนึงถึงไลบรารี คุณยังสามารถเลือกที่จะส่งคำขอแบบซิงโครนัสหรือแบบอะซิงโครนัส

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

การเพิ่มประสิทธิภาพการโหลดในโครงการ Highload ด้วย ElasticSearch

โปรโมชั่นใหญ่

ปีละครั้ง โปรเจกต์จะจัดโปรโมชันครั้งใหญ่สำหรับผู้ใช้ ซึ่งเป็น Highload เดียวกัน เนื่องจากในเวลานี้เราทำงานร่วมกับผู้ใช้หลายสิบล้านคนในเวลาเดียวกัน

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

เมื่อต้นปี 2019 เราตัดสินใจว่าเราต้องการ ElasticSearch ตลอดทั้งปี เราได้จัดระเบียบการประมวลผลข้อมูลที่ได้รับใน Elastic และการเผยแพร่ใน API ของแอปพลิเคชันมือถือและเว็บไซต์ เป็นผลให้ในปีถัดไประหว่างแคมเปญเราดำเนินการ 15 รายการใน 131 นาที

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

บทสรุป/บทสรุป

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

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

หากเราต้องการการค้นหาข้อความแบบเต็มในฟังก์ชันการทำงานหรือหากเรามีเกณฑ์การค้นหาที่แตกต่างกันมาก เราก็ทราบแล้วว่าสิ่งนี้จำเป็นต้องแปลเป็น Elastic

⌘⌘⌘

ขอบคุณที่อ่าน. หากบริษัทของคุณใช้ ElasticSearch และมีกรณีการใช้งานของตนเองด้วย โปรดแจ้งให้เราทราบ มันจะน่าสนใจที่จะรู้ว่าคนอื่นเป็นอย่างไร 🙂

ที่มา: will.com

เพิ่มความคิดเห็น