ทฤษฎีและการปฏิบัติการใช้ HBase

สวัสดีตอนบ่าย ฉันชื่อ Danil Lipovoy ทีมงานของเราที่ Sbertech เริ่มใช้ HBase เป็นที่จัดเก็บข้อมูลการปฏิบัติงาน ระหว่างที่ศึกษาก็สะสมประสบการณ์จนอยากจัดระบบและบรรยาย (หวังว่าจะเป็นประโยชน์กับหลายๆ คนนะครับ) การทดลองด้านล่างทั้งหมดถูกดำเนินการด้วย HBase เวอร์ชัน 1.2.0-cdh5.14.2 และ 2.0.0-cdh6.0.0-beta1

  1. สถาปัตยกรรมทั่วไป
  2. กำลังเขียนข้อมูลไปยัง HBASE
  3. การอ่านข้อมูลจาก HBASE
  4. การแคชข้อมูล
  5. การประมวลผลข้อมูลเป็นกลุ่ม MultiGet/MultiPut
  6. กลยุทธ์การแบ่งตารางออกเป็นขอบเขต (splitting)
  7. ความทนทานต่อข้อผิดพลาด การบีบอัดข้อมูล และตำแหน่งข้อมูล
  8. การตั้งค่าและประสิทธิภาพ
  9. การทดสอบความเครียด
  10. ผลการวิจัย

1. สถาปัตยกรรมทั่วไป

ทฤษฎีและการปฏิบัติการใช้ HBase
ต้นแบบสำรองจะฟังการเต้นของหัวใจของตัวที่ทำงานอยู่บนโหนด ZooKeeper และในกรณีที่หายไป จะเข้ารับหน้าที่ของตัวหลัก

2. เขียนข้อมูลไปยัง HBASE

ขั้นแรก มาดูกรณีที่ง่ายที่สุด - การเขียนออบเจ็กต์คีย์-ค่าลงในตารางโดยใช้ put(rowkey) ไคลเอนต์จะต้องค้นหาก่อนว่า Root Region Server (RRS) ซึ่งจัดเก็บตาราง hbase:meta ตั้งอยู่ที่ไหน เขาได้รับข้อมูลนี้จาก ZooKeeper หลังจากนั้นจะเข้าถึง RRS และอ่านตาราง hbase:meta ซึ่งจะดึงข้อมูลว่า RegionServer (RS) ใดที่รับผิดชอบในการจัดเก็บข้อมูลสำหรับคีย์แถวที่ระบุในตารางที่สนใจ สำหรับการใช้งานในอนาคต ตารางเมตาจะถูกแคชโดยไคลเอนต์ ดังนั้นการโทรครั้งต่อไปจะเร็วขึ้นโดยตรงไปยัง RS

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

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

ทฤษฎีและการปฏิบัติการใช้ HBase
เมื่อดำเนินการ "ลบ" ข้อมูลจะไม่ถูกลบทางกายภาพ พวกเขาจะถูกทำเครื่องหมายว่าลบแล้วและการทำลายล้างจะเกิดขึ้นในขณะที่เรียกใช้ฟังก์ชันคอมแพคหลักซึ่งอธิบายไว้ในรายละเอียดเพิ่มเติมในย่อหน้าที่ 7

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

นอกเหนือจากกระบวนการโหลดที่อธิบายไว้ข้างต้นแล้ว ยังมีขั้นตอนที่มีประสิทธิภาพมากกว่ามาก ซึ่งบางทีอาจเป็นด้านที่แข็งแกร่งที่สุดของฐานข้อมูลนี้ - BulkLoad อยู่ที่ความจริงที่ว่าเราสร้าง HFiles และวางไว้บนดิสก์อย่างอิสระซึ่งช่วยให้เราสามารถปรับขนาดได้อย่างสมบูรณ์แบบและบรรลุความเร็วที่เหมาะสมมาก ที่จริงแล้ว ข้อจำกัดที่นี่ไม่ใช่ HBase แต่เป็นความสามารถของฮาร์ดแวร์ ด้านล่างนี้คือผลลัพธ์การบูตบนคลัสเตอร์ที่ประกอบด้วย 16 RegionServers และ 16 NodeManager YARN (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 เธรด), HBase เวอร์ชัน 1.2.0-cdh5.14.2

ทฤษฎีและการปฏิบัติการใช้ HBase

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

คุณยังสามารถเริ่มโหลดลงในสองตารางในเวลาเดียวกันและเพิ่มความเร็วเป็นสองเท่าได้ ด้านล่างนี้ คุณจะเห็นว่าการเขียนบล็อกขนาด 10 KB ไปยังสองตารางพร้อมกันนั้นเกิดขึ้นที่ความเร็วประมาณ 600 MB/วินาทีในแต่ละบล็อก (รวม 1275 MB/วินาที) ซึ่งเกิดขึ้นพร้อมกับความเร็วในการเขียนลงในตารางเดียวที่ 623 MB/วินาที (ดู หมายเลข 11 ข้างต้น)

ทฤษฎีและการปฏิบัติการใช้ HBase
แต่การรันครั้งที่สองด้วยบันทึกขนาด 50 KB แสดงให้เห็นว่าความเร็วในการดาวน์โหลดเพิ่มขึ้นเล็กน้อย ซึ่งบ่งชี้ว่ากำลังเข้าใกล้ค่าขีดจำกัด ในเวลาเดียวกัน คุณต้องจำไว้ว่าในทางปฏิบัติแล้วไม่มีโหลดที่สร้างขึ้นบน HBASE สิ่งที่คุณต้องทำก็แค่ให้ข้อมูลจาก hbase:meta ก่อน และหลังจากซับ HFiles แล้ว ให้รีเซ็ตข้อมูล BlockCache และบันทึก MemStore บัฟเฟอร์ไปยังดิสก์ หากไม่ว่างเปล่า

3. การอ่านข้อมูลจาก HBASE

หากเราถือว่าไคลเอ็นต์มีข้อมูลทั้งหมดจาก hbase:meta แล้ว (ดูจุดที่ 2) คำขอจะถูกส่งไปยัง RS โดยตรงซึ่งเป็นที่จัดเก็บคีย์ที่ต้องการ ขั้นแรกให้ทำการค้นหาใน MemCache ไม่ว่าจะมีข้อมูลอยู่หรือไม่ก็ตาม การค้นหาจะดำเนินการในบัฟเฟอร์ BlockCache และใน HFiles หากจำเป็น หากพบข้อมูลในไฟล์ ข้อมูลนั้นจะถูกวางไว้ใน BlockCache และจะถูกส่งกลับเร็วขึ้นในคำขอครั้งต่อไป การค้นหาใน HFile นั้นค่อนข้างรวดเร็วด้วยการใช้ตัวกรอง Bloom เช่น เมื่ออ่านข้อมูลจำนวนเล็กน้อย ระบบจะกำหนดทันทีว่าไฟล์นี้มีคีย์ที่ต้องการหรือไม่ และหากไม่มี ก็จะไปยังไฟล์ถัดไป

ทฤษฎีและการปฏิบัติการใช้ HBase
เมื่อได้รับข้อมูลจากแหล่งข้อมูลทั้งสามนี้ RS จะสร้างการตอบสนอง โดยเฉพาะอย่างยิ่งสามารถถ่ายโอนอ็อบเจ็กต์ที่พบหลายเวอร์ชันพร้อมกันได้หากไคลเอนต์ร้องขอการกำหนดเวอร์ชัน

4. การแคชข้อมูล

บัฟเฟอร์ MemStore และ BlockCache ใช้พื้นที่มากถึง 80% ของหน่วยความจำ RS บนฮีปที่จัดสรร (ส่วนที่เหลือสงวนไว้สำหรับงานบริการ RS) หากโหมดการใช้งานทั่วไปเป็นเช่นนั้นกระบวนการเขียนและอ่านข้อมูลเดียวกันทันที ก็สมเหตุสมผลที่จะลด BlockCache และเพิ่ม MemStore เนื่องจาก เมื่อเขียนข้อมูลไม่เข้าแคชเพื่ออ่าน BlockCache จะถูกใช้งานน้อยลง บัฟเฟอร์ BlockCache ประกอบด้วยสองส่วน: LruBlockCache (อยู่บนฮีปเสมอ) และ BucketCache (โดยปกติจะเป็นแบบออฟฮีปหรือบน SSD) ควรใช้ BucketCache เมื่อมีคำขออ่านจำนวนมากและไม่เหมาะกับ LruBlockCache ซึ่งทำให้ Garbage Collector ทำงานอย่างต่อเนื่อง ในเวลาเดียวกันคุณไม่ควรคาดหวังประสิทธิภาพที่เพิ่มขึ้นอย่างมากจากการใช้แคชการอ่าน แต่เราจะกลับมาที่สิ่งนี้ในย่อหน้าที่ 8

ทฤษฎีและการปฏิบัติการใช้ HBase
มีหนึ่ง BlockCache สำหรับ RS ทั้งหมด และมีหนึ่ง MemStore สำหรับแต่ละตาราง (หนึ่งรายการสำหรับแต่ละตระกูลคอลัมน์)

ในขณะที่ อธิบายไว้ ตามทฤษฎีเมื่อเขียนข้อมูลจะไม่เข้าไปในแคชและแท้จริงแล้วพารามิเตอร์ดังกล่าว CACHE_DATA_ON_WRITE สำหรับตารางและ "ข้อมูลแคชเมื่อเขียน" สำหรับ RS ถูกตั้งค่าเป็นเท็จ อย่างไรก็ตาม ในทางปฏิบัติ ถ้าเราเขียนข้อมูลลงใน MemStore จากนั้นให้ล้างข้อมูลลงดิสก์ (โดยทำการล้างข้อมูล) จากนั้นจึงลบไฟล์ผลลัพธ์ จากนั้นดำเนินการตามคำขอ get เราก็จะได้รับข้อมูลได้สำเร็จ ยิ่งไปกว่านั้น แม้ว่าคุณจะปิดใช้งาน BlockCache โดยสมบูรณ์และเติมข้อมูลใหม่ลงในตาราง จากนั้นรีเซ็ต MemStore ไปยังดิสก์ ลบและร้องขอจากเซสชันอื่น ข้อมูลเหล่านั้นจะยังคงถูกดึงมาจากที่ไหนสักแห่ง ดังนั้น HBase จึงไม่เพียงแต่จัดเก็บข้อมูลเท่านั้น แต่ยังรวมถึงความลึกลับอันลึกลับอีกด้วย

hbase(main):001:0> create 'ns:magic', 'cf'
Created table ns:magic
Took 1.1533 seconds
hbase(main):002:0> put 'ns:magic', 'key1', 'cf:c', 'try_to_delete_me'
Took 0.2610 seconds
hbase(main):003:0> flush 'ns:magic'
Took 0.6161 seconds
hdfs dfs -mv /data/hbase/data/ns/magic/* /tmp/trash
hbase(main):002:0> get 'ns:magic', 'key1'
 cf:c      timestamp=1534440690218, value=try_to_delete_me

พารามิเตอร์ "ข้อมูลแคชเมื่ออ่าน" ถูกตั้งค่าเป็นเท็จ หากคุณมีความคิดใด ๆ ยินดีที่จะพูดคุยในความคิดเห็น

5. การประมวลผลข้อมูลแบบแบตช์ MultiGet/MultiPut

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

ทฤษฎีและการปฏิบัติการใช้ HBase

ทำการทดสอบบนเครื่องเสมือน 8 คอร์ เวอร์ชัน HBase 2.0.0-cdh6.0.0-beta1

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

ทฤษฎีและการปฏิบัติการใช้ HBase
นอกจากการเพิ่มขนาดเป็นชิ้นแล้ว การแบ่งข้อมูลตามภูมิภาคยังช่วยได้ เช่น การแยกตาราง ส่งผลให้มีคำขอมายังแต่ละภูมิภาคน้อยลง และหากคำขอเหล่านั้นพอดีกับเซลล์ การตอบสนองจะยังคงดีอยู่

6. กลยุทธ์การแบ่งตารางออกเป็นขอบเขต (splitting)

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

ทฤษฎีและการปฏิบัติการใช้ HBase
มันเกิดขึ้นที่สิ่งนี้นำไปสู่การชะลอตัวลงอย่างมากหากข้อมูลที่โหลดในภายหลังมีลักษณะเช่นค่ายาว ซึ่งส่วนใหญ่เริ่มต้นด้วยตัวเลขเดียวกัน เช่น:

1000001
1000002
...
1100003

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

HexStringSplit – เปลี่ยนคีย์ให้เป็นสตริงที่เข้ารหัสเลขฐานสิบหกในช่วง "00000000" => "FFFFFFFF" และเติมด้านซ้ายด้วยศูนย์

UniformSplit – เปลี่ยนคีย์ให้เป็นอาร์เรย์ไบต์ด้วยการเข้ารหัสเลขฐานสิบหกในช่วง "00" => "FF" และเติมทางด้านขวาด้วยศูนย์

นอกจากนี้ คุณยังสามารถระบุช่วงหรือชุดคีย์สำหรับการแยกและกำหนดค่าการแยกอัตโนมัติได้ อย่างไรก็ตาม หนึ่งในวิธีที่ง่ายและมีประสิทธิภาพมากที่สุดคือ UniformSplit และการใช้การต่อแฮช เช่น คู่ไบต์ที่สำคัญที่สุดจากการรันคีย์ผ่านฟังก์ชัน CRC32(rowkey) และ Rowkey เอง:

แฮช + คีย์แถว

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

7. ความทนทานต่อข้อผิดพลาดและตำแหน่งข้อมูล

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

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

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

ทฤษฎีและการปฏิบัติการใช้ HBase
การทดสอบดำเนินการบน 3 DataNodes และ 4 RS (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 เธรด) HBase เวอร์ชัน 1.2.0-cdh5.14.2

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

นอกจากนี้ การบดอัดหลักจะไม่ส่งผลต่อสถานะของ MemStore หากต้องการล้างข้อมูลลงดิสก์และกระชับข้อมูล คุณต้องใช้การล้างข้อมูล (connection.getAdmin().flush(TableName.valueOf(tblName)))

8. การตั้งค่าและประสิทธิภาพ

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

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

-ใส่
-รับ
—รับ+ใส่

  • แต่ละบล็อกดำเนินการซ้ำ 50 ครั้ง
  • ขนาดบล็อกของบันทึกคือ 100 ไบต์, 1000 ไบต์ หรือ 10000 ไบต์ (สุ่ม)
  • บล็อกถูกเปิดใช้งานโดยมีจำนวนคีย์ที่ร้องขอต่างกัน (คีย์เดียวหรือ 10 คีย์)
  • บล็อกถูกเรียกใช้ภายใต้การตั้งค่าตารางที่แตกต่างกัน พารามิเตอร์มีการเปลี่ยนแปลง:

— BlockCache = เปิดหรือปิด
— BlockSize = 65 KB หรือ 16 KB
— พาร์ติชัน = 1, 5 หรือ 30
— MSLAB = เปิดหรือปิดใช้งาน

ดังนั้นบล็อกจึงมีลักษณะดังนี้:

ก. โหมด MSLAB ถูกเปิด/ปิด
ข. ตารางถูกสร้างขึ้นโดยมีการตั้งค่าพารามิเตอร์ต่อไปนี้: BlockCache = true/none, BlockSize = 65/16 Kb, พาร์ติชัน = 1/5/30
ค. การบีบอัดถูกตั้งค่าเป็น GZ
ง. มีการเปิดตัว 10 เธรดพร้อมกัน โดยดำเนินการ 1/10 put/get/get+put ในตารางนี้ โดยมีบันทึกขนาด 100/1000/10000 ไบต์ ดำเนินการ 50 คิวรีในแถว (คีย์สุ่ม)
จ. จุด d ซ้ำสามครั้ง
ฉ. เวลาการทำงานของเธรดทั้งหมดเป็นค่าเฉลี่ย

ชุดค่าผสมที่เป็นไปได้ทั้งหมดได้รับการทดสอบ เป็นที่คาดเดาได้ว่าความเร็วจะลดลงเมื่อขนาดบันทึกเพิ่มขึ้น หรือการปิดใช้งานแคชจะทำให้ช้าลง อย่างไรก็ตาม เป้าหมายคือการเข้าใจระดับและความสำคัญของอิทธิพลของแต่ละพารามิเตอร์ ดังนั้นข้อมูลที่รวบรวมไว้จึงถูกป้อนเข้าในฟังก์ชันการถดถอยเชิงเส้น ซึ่งทำให้สามารถประเมินนัยสำคัญโดยใช้สถิติ t ด้านล่างนี้คือผลลัพธ์ของบล็อกที่ดำเนินการ Put ชุดค่าผสมครบชุด 2*2*3*2*3 = 144 ตัวเลือก + 72 tk บ้างก็ทำสองครั้ง จึงมีทั้งหมด 216 รอบ:

ทฤษฎีและการปฏิบัติการใช้ HBase
การทดสอบดำเนินการบนมินิคลัสเตอร์ซึ่งประกอบด้วย 3 DataNodes และ 4 RS (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 เธรด) HBase เวอร์ชัน 1.2.0-cdh5.14.2

ได้รับความเร็วการแทรกสูงสุดที่ 3.7 วินาทีเมื่อปิดโหมด MSLAB บนโต๊ะที่มีหนึ่งพาร์ติชัน โดยเปิดใช้งาน BlockCache BlockSize = 16 บันทึก 100 ไบต์ 10 ชิ้นต่อแพ็ค
ได้รับความเร็วการแทรกต่ำสุดที่ 82.8 วินาทีเมื่อเปิดใช้งานโหมด MSLAB บนตารางที่มีหนึ่งพาร์ติชัน โดยเปิดใช้งาน BlockCache BlockSize = 16 บันทึก 10000 ไบต์ แต่ละ 1 อัน

ทีนี้มาดูโมเดลกันดีกว่า เราเห็นคุณภาพดีของแบบจำลองตาม R2 แต่เป็นที่ชัดเจนอย่างยิ่งว่าการคาดการณ์มีข้อห้ามที่นี่ พฤติกรรมที่แท้จริงของระบบเมื่อพารามิเตอร์เปลี่ยนแปลงจะไม่เป็นเชิงเส้น โมเดลนี้ไม่จำเป็นสำหรับการคาดการณ์ แต่สำหรับการทำความเข้าใจสิ่งที่เกิดขึ้นภายในพารามิเตอร์ที่กำหนด ตัวอย่างเช่น เราเห็นจากเกณฑ์ของนักเรียนว่าพารามิเตอร์ BlockSize และ BlockCache ไม่สำคัญสำหรับการดำเนินการ Put (ซึ่งโดยทั่วไปค่อนข้างคาดเดาได้):

ทฤษฎีและการปฏิบัติการใช้ HBase
แต่ความจริงที่ว่าการเพิ่มจำนวนพาร์ติชันทำให้ประสิทธิภาพลดลงนั้นค่อนข้างไม่คาดคิด (เราได้เห็นผลกระทบเชิงบวกของการเพิ่มจำนวนพาร์ติชันด้วย BulkLoad แล้ว) แม้ว่าจะเข้าใจได้ก็ตาม ประการแรก สำหรับการประมวลผล คุณต้องสร้างคำขอไปยัง 30 ภูมิภาคแทนที่จะเป็นหนึ่งภูมิภาค และปริมาณข้อมูลไม่ได้มากจนทำให้ได้รับผลเพิ่มขึ้น ประการที่สอง เวลาการทำงานทั้งหมดถูกกำหนดโดย RS ที่ช้าที่สุด และเนื่องจากจำนวน DataNodes น้อยกว่าจำนวน RS บางภูมิภาคจึงมีพื้นที่เป็นศูนย์ มาดูห้าอันดับแรกกันดีกว่า:

ทฤษฎีและการปฏิบัติการใช้ HBase
ตอนนี้เรามาประเมินผลลัพธ์ของการดำเนินการรับบล็อก:

ทฤษฎีและการปฏิบัติการใช้ HBase
จำนวนพาร์ติชันสูญเสียความสำคัญไป ซึ่งอาจอธิบายได้จากข้อเท็จจริงที่ว่าข้อมูลถูกแคชอย่างดี และแคชการอ่านเป็นพารามิเตอร์ที่สำคัญที่สุด (ตามสถิติ) โดยปกติแล้ว การเพิ่มจำนวนข้อความในคำขอก็มีประโยชน์อย่างมากต่อประสิทธิภาพเช่นกัน คะแนนสูงสุด:

ทฤษฎีและการปฏิบัติการใช้ HBase
ในที่สุด เรามาดูโมเดลของบล็อกที่ทำครั้งแรก get แล้วใส่:

ทฤษฎีและการปฏิบัติการใช้ HBase
พารามิเตอร์ทั้งหมดมีความสำคัญที่นี่ และผลลัพธ์ของผู้นำ:

ทฤษฎีและการปฏิบัติการใช้ HBase

9. การทดสอบโหลด

ในที่สุดเราก็จะเปิดตัวโหลดที่เหมาะสมไม่มากก็น้อย แต่จะน่าสนใจกว่าเสมอเมื่อคุณมีสิ่งที่จะเปรียบเทียบ บนเว็บไซต์ของ DataStax ซึ่งเป็นผู้พัฒนาหลักของ Cassandra มีอยู่ ผลลัพธ์ NT ของพื้นที่จัดเก็บ NoSQL จำนวนหนึ่ง รวมถึง HBase เวอร์ชัน 0.98.6-1 การโหลดดำเนินการโดย 40 เธรด ขนาดข้อมูล 100 ไบต์ ดิสก์ SSD ผลการทดสอบการดำเนินการอ่าน-แก้ไข-เขียนแสดงผลลัพธ์ดังนี้

ทฤษฎีและการปฏิบัติการใช้ HBase
เท่าที่ฉันเข้าใจ การอ่านดำเนินการในบล็อก 100 รายการและสำหรับโหนด HBase 16 รายการ การทดสอบ DataStax แสดงประสิทธิภาพ 10 การดำเนินการต่อวินาที

โชคดีที่คลัสเตอร์ของเรามี 16 โหนด แต่ก็ไม่ได้ "โชคดี" มากนักที่แต่ละโหนดมี 64 คอร์ (เธรด) ในขณะที่การทดสอบ DataStax มีเพียง 4 โหนด ในทางกลับกัน พวกเขามีไดรฟ์ SSD ในขณะที่เรามี HDD หรือมากกว่านั้นการใช้งาน HBase และ CPU เวอร์ชันใหม่ในระหว่างการโหลดไม่ได้เพิ่มขึ้นอย่างมีนัยสำคัญ (มองเห็นได้ 5-10 เปอร์เซ็นต์) อย่างไรก็ตาม เรามาลองเริ่มใช้การกำหนดค่านี้กันดีกว่า การตั้งค่าตารางเริ่มต้น การอ่านจะดำเนินการในช่วงคีย์ตั้งแต่ 0 ถึง 50 ล้านแบบสุ่ม (กล่าวคือ จะต้องใหม่ทุกครั้ง) ตารางประกอบด้วยบันทึก 50 ล้านรายการ แบ่งออกเป็น 64 พาร์ติชัน คีย์ถูกแฮชโดยใช้ crc32 การตั้งค่าตารางเป็นค่าเริ่มต้น MSLAB เปิดใช้งานอยู่ เปิดตัว 40 เธรด แต่ละเธรดจะอ่านชุดคีย์สุ่ม 100 อัน และเขียน 100 ไบต์ที่สร้างขึ้นกลับไปยังคีย์เหล่านี้ทันที

ทฤษฎีและการปฏิบัติการใช้ HBase
สแตนด์: 16 DataNode และ 16 RS (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 เธรด) HBase เวอร์ชัน 1.2.0-cdh5.14.2

ผลลัพธ์โดยเฉลี่ยใกล้เคียงกับ 40 การดำเนินการต่อวินาที ซึ่งดีกว่าการทดสอบ DataStax อย่างมาก อย่างไรก็ตาม เพื่อวัตถุประสงค์ในการทดลอง คุณสามารถเปลี่ยนแปลงเงื่อนไขได้เล็กน้อย ไม่น่าเป็นไปได้ทีเดียวที่งานทั้งหมดจะดำเนินการเฉพาะบนโต๊ะเดียวและเฉพาะกับคีย์เฉพาะเท่านั้น สมมติว่ามีชุดคีย์ "ร้อน" บางชุดที่สร้างโหลดหลัก ดังนั้น เรามาลองสร้างโหลดด้วยบันทึกที่ใหญ่กว่า (10 KB) ในชุด 100 เช่นกัน ใน 4 ตารางที่แตกต่างกันและจำกัดช่วงของคีย์ที่ร้องขอไว้ที่ 50 กราฟด้านล่างแสดงการเปิดตัว 40 เธรด แต่ละเธรดจะอ่าน ชุดคีย์ 100 ปุ่มและเขียนสุ่ม 10 KB บนคีย์เหล่านี้กลับทันที

ทฤษฎีและการปฏิบัติการใช้ HBase
สแตนด์: 16 DataNode และ 16 RS (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 เธรด) HBase เวอร์ชัน 1.2.0-cdh5.14.2

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

การอ่านและการเขียนทันทีเป็นหนึ่งในสถานการณ์การทำงานที่ยากที่สุดสำหรับ HBase หากคุณส่งคำขอ Put เพียงเล็กน้อย เช่น 100 ไบต์ เมื่อรวมคำขอเหล่านั้นเป็นแพ็คที่มีจำนวน 10-50 ชิ้น คุณจะได้รับการดำเนินการนับแสนครั้งต่อวินาที และสถานการณ์จะคล้ายกับคำขอแบบอ่านอย่างเดียว เป็นที่น่าสังเกตว่าผลลัพธ์นั้นดีกว่าผลลัพธ์ที่ได้รับจาก DataStax อย่างมากส่วนใหญ่เกิดจากการร้องขอในบล็อก 50

ทฤษฎีและการปฏิบัติการใช้ HBase
สแตนด์: 16 DataNode และ 16 RS (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 เธรด) HBase เวอร์ชัน 1.2.0-cdh5.14.2

10. บทสรุป

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

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

ที่มา: will.com

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