6.1 ใครเป็นผู้คิดค้น HBase และทำไม

ในการบรรยายนี้ เราจะพูดถึงเครื่องมือที่ยอดเยี่ยมเช่น Hbase ซึ่งเพิ่งได้รับความนิยมอย่างมาก ตัวอย่างเช่น Facebook ใช้เป็นพื้นฐานของระบบการส่งข้อความ และนี่ก็พูดมากแล้ว

การบรรยายจะพูดถึงแนวคิดของ Big Table และการนำไปใช้ฟรี คุณลักษณะของงาน และความแตกต่างจากทั้งฐานข้อมูลเชิงสัมพันธ์แบบดั้งเดิม (เช่น MySQL และ Oracle) และพื้นที่จัดเก็บคีย์-ค่า เช่น Redis, Aerospike และ memcached เริ่มจากประวัติของปัญหาตามปกติ เช่นเดียวกับโครงการ BigData อื่นๆ Hbase เกิดจากแนวคิดที่พัฒนาโดย Google หลักการเบื้องหลัง Hbase ได้อธิบายไว้ใน บทความ Bigtable: A Distributed Storage System for Structured Data

ดังที่เราได้กล่าวถึงในการบรรยายครั้งก่อน ไฟล์ธรรมดาค่อนข้างเหมาะสมสำหรับการประมวลผลข้อมูลเป็นชุดโดยใช้กระบวนทัศน์ MapReduce ในทางกลับกัน ข้อมูลที่จัดเก็บไว้ในไฟล์ค่อนข้างไม่สะดวกที่จะอัปเดต ไฟล์ยังถูกกีดกันจากความเป็นไปได้ในการเข้าถึงแบบสุ่ม เพื่อการทำงานที่รวดเร็วและสะดวกด้วยการเข้าถึงแบบสุ่ม มีคลาสของระบบ nosql เช่น ที่จัดเก็บคีย์-ค่า เช่น Aerospike, Redis, Couchbase, Memcached อย่างไรก็ตาม การประมวลผลเป็นชุดมักจะไม่สะดวกในระบบเหล่านี้ Hbase เป็นความพยายามที่จะรวมความสะดวกในการประมวลผลแบบแบตช์เข้ากับความสะดวกในการอัปเดตและการเข้าถึงแบบสุ่ม

6.2 แบบจำลองข้อมูล

HBase เป็นฐานข้อมูลคีย์-ค่าหลายเวอร์ชันแบบกระจาย เน้นคอลัมน์

  • ข้อมูลถูกจัดระเบียบเป็นตารางที่จัดทำดัชนีโดยคีย์หลักที่เรียกว่า RowKey ใน Hbase
  • สำหรับแต่ละคีย์ RowKey สามารถจัดเก็บชุดแอตทริบิวต์ (หรือคอลัมน์) ได้ไม่จำกัด
  • คอลัมน์ถูกจัดเป็นกลุ่มของคอลัมน์ที่เรียกว่า Column Family ตามกฎแล้ว คอลัมน์ที่มีการใช้งานและรูปแบบการจัดเก็บเหมือนกันจะรวมกันเป็นตระกูลคอลัมน์เดียว
  • สำหรับแต่ละแอตทริบิวต์ สามารถจัดเก็บเวอร์ชันต่างๆ ได้หลายเวอร์ชัน เวอร์ชันต่างๆ จะมีการประทับเวลาที่ต่างกัน

บันทึกจะถูกจัดเก็บทางกายภาพตามลำดับการจัดเรียงของ RowKey ในกรณีนี้ ข้อมูลที่สอดคล้องกับตระกูลคอลัมน์ต่างๆ จะถูกจัดเก็บแยกจากกัน ซึ่งทำให้สามารถอ่านข้อมูลจากตระกูลคอลัมน์ที่ต้องการได้หากจำเป็น

เมื่อแอตทริบิวต์บางอย่างถูกลบ จะไม่ถูกลบในทันที แต่จะทำเครื่องหมายด้วยธงหลุมฝังศพพิเศษเท่านั้น การลบข้อมูลทางกายภาพจะเกิดขึ้นในภายหลัง เมื่อมีการดำเนินการบีบอัดครั้งใหญ่

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

ชื่อกลุ่มรายการและคอลัมน์ได้รับการแก้ไขและมีเค้าโครงที่ชัดเจน ที่ระดับกลุ่มคอลัมน์ พารามิเตอร์ต่างๆ เช่น time to live (TTL) และจำนวนสูงสุดของเวอร์ชันที่เก็บไว้จะถูกตั้งค่า หากความแตกต่างระหว่างการประทับเวลาสำหรับเวอร์ชันใดเวอร์ชันหนึ่งและเวลาปัจจุบันมากกว่า TTL รายการจะถูกทำเครื่องหมายเพื่อลบ ถ้าจำนวนของเวอร์ชันสำหรับแอตทริบิวต์บางอย่างเกินจำนวนเวอร์ชันสูงสุด เรกคอร์ดจะถูกทำเครื่องหมายเพื่อลบด้วย

โมเดลข้อมูล Hbase สามารถจดจำได้ว่าเป็นคีย์-ค่าที่ตรงกัน:

<table, RowKey, Column Family, Column, timestamp> -> Value

6.3 การดำเนินการที่สนับสนุน

รายการการดำเนินการที่รองรับใน hbase นั้นค่อนข้างง่าย รองรับการทำงานหลัก 4 อย่าง:

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

6.4 สถาปัตยกรรม

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

HBase ใช้สองกระบวนการหลักในการทำงาน:

1. เซิร์ฟเวอร์ภูมิภาค - ให้บริการหนึ่งภูมิภาคหรือมากกว่า ขอบเขตคือช่วงของเรกคอร์ดที่สอดคล้องกับช่วงเฉพาะของ RowKeys ที่ต่อเนื่องกัน แต่ละภูมิภาคประกอบด้วย:

  • Persistent Storageเป็นที่เก็บข้อมูลหลักใน HBase ข้อมูลถูกจัดเก็บจริงบน HDFS ในรูปแบบ HFile พิเศษ ข้อมูลใน HFile จะถูกจัดเก็บไว้ในลำดับการจัดเรียงของ RowKey หนึ่งคู่ (ภูมิภาค ตระกูลคอลัมน์) สอดคล้องกับ HFIle อย่างน้อยหนึ่งรายการ
  • MemStore - บัฟเฟอร์การเขียน เนื่องจากข้อมูลถูกจัดเก็บไว้ใน HFile d ตามลำดับ การอัพเดต HFile ต่อเรคคอร์ดจึงค่อนข้างแพง เมื่อเขียนข้อมูลจะเข้าสู่พื้นที่หน่วยความจำ MemStore พิเศษซึ่งจะสะสมอยู่ระยะหนึ่ง เมื่อ MemStore เต็มไปด้วยค่าวิกฤต ข้อมูลจะถูกเขียนไปยัง HFile ใหม่
  • BlockCache - แคชสำหรับการอ่าน ช่วยให้คุณประหยัดเวลาอย่างมากกับข้อมูลที่อ่านบ่อย
  • เขียนบันทึกล่วงหน้า (WAL ) เนื่องจากข้อมูลถูกเขียนไปยัง memstore จึงมีความเสี่ยงที่ข้อมูลจะสูญหายเนื่องจากการหยุดทำงาน เพื่อป้องกันไม่ให้สิ่งนี้เกิดขึ้น การดำเนินการทั้งหมดก่อนการใช้งานจริงจะอยู่ในล็อกไฟล์พิเศษ สิ่งนี้ทำให้คุณสามารถกู้คืนข้อมูลได้หลังจากเกิดความล้มเหลว

2. เซิร์ฟเวอร์หลัก - เซิร์ฟเวอร์หลักในคลัสเตอร์ HBase Master จัดการการกระจายของภูมิภาคระหว่างเซิร์ฟเวอร์ภูมิภาค ดูแลรักษาการลงทะเบียนของภูมิภาค จัดการการเปิดตัวของงานปกติ และทำงานที่เป็นประโยชน์อื่น ๆ

เพื่อประสานการดำเนินการระหว่างบริการ HBase ใช้ Apache ZooKeeper ซึ่งเป็นบริการพิเศษที่ออกแบบมาเพื่อจัดการการกำหนดค่าและซิงโครไนซ์บริการ

เมื่อจำนวนข้อมูลในขอบเขตเพิ่มขึ้นและถึงขนาดที่กำหนด Hbase จะเริ่มแยก ซึ่งเป็นการดำเนินการที่แบ่งภูมิภาคออกเป็น 2 ส่วนเพื่อหลีกเลี่ยงการแบ่งภูมิภาคอย่างต่อเนื่อง คุณสามารถกำหนดขอบเขตของภูมิภาคล่วงหน้าและเพิ่มค่าสูงสุดได้ ขนาด.

เนื่องจากข้อมูลสำหรับภูมิภาคเดียวสามารถจัดเก็บไว้ใน HFile หลายไฟล์ได้ Hbase จึงรวมข้อมูลเหล่านี้เข้าด้วยกันเป็นระยะๆ เพื่อเพิ่มความเร็วในการทำงาน การดำเนินการนี้เรียกว่าการบดอัดใน Hbase การบดอัดมีสองประเภท:

  • การบดอัดเล็กน้อย เริ่มโดยอัตโนมัติ ทำงานในพื้นหลัง มีลำดับความสำคัญต่ำเมื่อเทียบกับการดำเนินการ Hbase อื่น ๆ
  • การบดอัดที่สำคัญ มันถูกเปิดใช้งานด้วยมือหรือเมื่อเกิดทริกเกอร์บางอย่าง (เช่น โดยตัวจับเวลา) มีลำดับความสำคัญสูงและสามารถทำให้คลัสเตอร์ช้าลงอย่างมาก การบีบอัดหลักทำได้ดีที่สุดในเวลาที่โหลดบนคลัสเตอร์มีขนาดเล็ก Major Compaction ยังลบข้อมูลที่ทำเครื่องหมายไว้ก่อนหน้านี้ด้วยศิลาหน้าหลุมฝังศพด้วย

6.5 วิธีการทำงานกับ HBase

เอชเบสเชลล์

วิธีที่ง่ายที่สุดในการเริ่มต้นใช้งาน Hbase คือการใช้ยูทิลิตี้เชลล์ hbase พร้อมใช้งานทันทีหลังจากติดตั้ง hbase บนโหนดคลัสเตอร์ hbase

Hbase shell เป็นคอนโซล jruby พร้อมการสนับสนุนในตัวสำหรับการดำเนินการ Hbase พื้นฐานทั้งหมด ต่อไปนี้เป็นตัวอย่างของการสร้างตารางผู้ใช้ที่มีสองตระกูลคอลัมน์ ดำเนินการบางอย่างกับมัน และวางตารางที่ส่วนท้ายในเชลล์ hbase:

create 'users', {NAME => 'user_profile', VERSIONS => 5}, {NAME => 'user_posts', VERSIONS => 1231231231} 
put 'users', 'id1', 'user_profile:name', 'alexander' 
put 'users', 'id1', 'user_profile:second_name', 'alexander' 
get 'users', 'id1' 
put 'users', 'id1', 'user_profile:second_name', 'kuznetsov' 
get 'users', 'id1' 
get 'users', 'id1', {COLUMN => 'user_profile:second_name', VERSIONS => 5} 
put 'users', 'id2', 'user_profile:name', 'vasiliy' 
put 'users', 'id2', 'user_profile:second_name', 'ivanov' 
scan 'users', {COLUMN => 'user_profile:second_name', VERSIONS => 5} 
delete 'users', 'id1', 'user_profile:second_name' 
get 'users', 'id1' 
disable 'users' 
drop 'users'

API เนทีฟ

เช่นเดียวกับโปรเจ็กต์ที่เกี่ยวข้องกับ Hadoop อื่นๆ ส่วนใหญ่ hbase ใช้งานใน java ดังนั้น native api จึงพร้อมใช้งานใน Java Native API ได้รับการบันทึกไว้อย่างดีในเว็บไซต์อย่างเป็นทางการ นี่คือตัวอย่างของการใช้ Hbase API ที่นำมาจากที่นั่น:

import java.io.IOException;

import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

public class MyLittleHBaseClient {
  public static void main(String[] args) throws IOException {
	Configuration config = HBaseConfiguration.create();
	Connection connection = ConnectionFactory.createConnection(config);
	try {
  	Table table = connection.getTable(TableName.valueOf("myLittleHBaseTable"));
  	try {
    	Put p = new Put(Bytes.toBytes("myLittleRow"));
    	p.add(Bytes.toBytes("myLittleFamily"), Bytes.toBytes("someQualifier"),
    	Bytes.toBytes("Some Value"));
    	table.put(p);

    	Get g = new Get(Bytes.toBytes("myLittleRow"));
    	Result r = table.get(g);
    	byte [] value = r.getValue(Bytes.toBytes("myLittleFamily"),
      	Bytes.toBytes("someQualifier"));

    	String valueStr = Bytes.toString(value);
    	System.out.println("GET: " + valueStr);

    	Scan s = new Scan();
    	s.addColumn(Bytes.toBytes("myLittleFamily"), Bytes.toBytes("someQualifier"));
    	ResultScanner scanner = table.getScanner(s);
    	try {
       	for (Result rr = scanner.next(); rr != null; rr = scanner.next()) {
         	System.out.println("Found row: " + rr);
       	}
     	} finally {
       	scanner.close();
     	}
   	} finally {
     	if (table != null) table.close();
   	}
 	} finally {
   	connection.close();
 	}
  }
}

Thrift, REST และรองรับภาษาโปรแกรมอื่นๆ

ในการทำงานจากภาษาการเขียนโปรแกรมอื่น Hbase มี Thrift API และ Rest API ไคลเอนต์ถูกสร้างขึ้นสำหรับภาษาโปรแกรมหลักทั้งหมด: python, PHP, Java Script เป็นต้น

6.6 คุณสมบัติบางอย่างของการทำงานกับ HBase

  1. Hbase ผสานรวมกับ MapReduce นอกกรอบ และสามารถใช้เป็นอินพุตและเอาต์พุตโดยใช้ TableInputFormat และ TableOutputFormat พิเศษ

  2. การเลือก RowKey ที่เหมาะสมเป็นสิ่งสำคัญมาก RowKey ต้องจัดเตรียมการกระจายที่ดีอย่างสม่ำเสมอทั่วทั้งภูมิภาค มิฉะนั้นจะมีความเสี่ยงของสิ่งที่เรียกว่า "ภูมิภาคร้อน" ซึ่งเป็นภูมิภาคที่มีการใช้งานบ่อยกว่าภูมิภาคอื่น ซึ่งนำไปสู่การใช้ทรัพยากรระบบที่ไม่มีประสิทธิภาพ

  3. หากไม่ได้อัปโหลดข้อมูลเดี่ยวๆ แต่ทันทีเป็นชุดใหญ่ Hbase รองรับกลไก BulkLoad พิเศษที่ช่วยให้คุณอัปโหลดข้อมูลได้เร็วกว่าการใช้ Puts เดียว BulkLoad เป็นการดำเนินการสองขั้นตอน:

    • การก่อตัวของ HFile โดยไม่ต้องมีส่วนร่วมของงาน MapReduce พิเศษ
    • การแทรกไฟล์เหล่านี้ลงใน Hbase โดยตรง
  4. Hbase รองรับเอาต์พุตเมตริกไปยังเซิร์ฟเวอร์การมอนิเตอร์ Ganglia สิ่งนี้มีประโยชน์มากเมื่อจัดการ Hbase เพื่อไปที่ด้านล่างสุดของปัญหา hbase

คีย์แถว

RowKey คือ ID ผู้ใช้ซึ่งเป็น GUUID ซึ่งเป็นสตริงที่สร้างขึ้นเป็นพิเศษเพื่อให้ไม่ซ้ำกันทั่วโลก GUUID มีการกระจายอย่างเท่าเทียมกัน ซึ่งให้การกระจายข้อมูลที่ดีทั่วทั้งเซิร์ฟเวอร์

ครอบครัวคอลัมน์

ที่เก็บข้อมูลของเราใช้สองตระกูลคอลัมน์:

  • ข้อมูล. คอลัมน์กลุ่มนี้เก็บข้อมูลที่ไม่เกี่ยวข้องกับวัตถุประสงค์ในการโฆษณาอีกต่อไป เช่น ข้อเท็จจริงที่ว่าผู้ใช้ได้เข้าชมบาง URL TTL สำหรับตระกูลคอลัมน์นี้ถูกตั้งค่าเป็น 2 เดือน จำนวนเวอร์ชันสูงสุดคือ 2,000
  • ข้อมูลยาว คอลัมน์กลุ่มนี้เก็บข้อมูลที่ไม่สูญเสียความเกี่ยวข้องเมื่อเวลาผ่านไป เช่น เพศ วันเกิด และคุณลักษณะอื่นๆ ของผู้ใช้ "นิรันดร์"

ลำโพง

ข้อเท็จจริงของผู้ใช้แต่ละประเภทจะถูกจัดเก็บไว้ในคอลัมน์แยกต่างหาก ตัวอย่างเช่น คอลัมน์ Data:_v จะจัดเก็บ URL ที่ผู้ใช้เยี่ยมชม และคอลัมน์ LongData:gender จะจัดเก็บเพศของผู้ใช้

การประทับเวลาของข้อเท็จจริงนี้จะถูกจัดเก็บเป็นการประทับเวลา ตัวอย่างเช่น ในคอลัมน์ Data:_v การประทับเวลาคือเวลาที่ผู้ใช้เข้าชม URL หนึ่งๆ

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

6.7 ทางเลือก

HBase ค่อนข้างซับซ้อนในการจัดการและใช้งาน ดังนั้นก่อนที่จะใช้ HBase คุณควรพิจารณาทางเลือกอื่น:

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

  • ที่เก็บคีย์-ค่า พื้นที่เก็บข้อมูลอย่าง Redis และ Aerospike นั้นเหมาะสมกว่าเมื่อต้องการเวลาแฝง และการประมวลผลเป็นชุดมีความสำคัญน้อยกว่า

  • ไฟล์และการประมวลผลด้วย MapReduce หากมีการเพิ่มข้อมูลเท่านั้นและไม่ค่อยอัปเดต/เปลี่ยนแปลง เป็นการดีกว่าที่จะไม่ใช้ HBase แต่เพียงแค่เก็บข้อมูลไว้ในไฟล์ เพื่อลดความซับซ้อนในการทำงานกับไฟล์ คุณสามารถใช้เครื่องมือต่างๆ เช่น Hive, Pig และ Impala

การใช้ HBase นั้นสมเหตุสมผลเมื่อ:

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