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 เป็นความพยายามที่จะรวมความสะดวกในการประมวลผลแบบแบตช์เข้ากับความสะดวกในการอัปเดตและการเข้าถึงแบบสุ่ม
![](https://cdn.codegym.cc/images/article/54d64a29-4642-4c59-8211-2b143dfcd48a/512.jpeg)
6.2 แบบจำลองข้อมูล
HBase เป็นฐานข้อมูลคีย์-ค่าหลายเวอร์ชันแบบกระจาย เน้นคอลัมน์
- ข้อมูลถูกจัดระเบียบเป็นตารางที่จัดทำดัชนีโดยคีย์หลักที่เรียกว่า RowKey ใน Hbase
- สำหรับแต่ละคีย์ RowKey สามารถจัดเก็บชุดแอตทริบิวต์ (หรือคอลัมน์) ได้ไม่จำกัด
- คอลัมน์ถูกจัดเป็นกลุ่มของคอลัมน์ที่เรียกว่า Column Family ตามกฎแล้ว คอลัมน์ที่มีการใช้งานและรูปแบบการจัดเก็บเหมือนกันจะรวมกันเป็นตระกูลคอลัมน์เดียว
- สำหรับแต่ละแอตทริบิวต์ สามารถจัดเก็บเวอร์ชันต่างๆ ได้หลายเวอร์ชัน เวอร์ชันต่างๆ จะมีการประทับเวลาที่ต่างกัน
บันทึกจะถูกจัดเก็บทางกายภาพตามลำดับการจัดเรียงของ RowKey ในกรณีนี้ ข้อมูลที่สอดคล้องกับตระกูลคอลัมน์ต่างๆ จะถูกจัดเก็บแยกจากกัน ซึ่งทำให้สามารถอ่านข้อมูลจากตระกูลคอลัมน์ที่ต้องการได้หากจำเป็น
เมื่อแอตทริบิวต์บางอย่างถูกลบ จะไม่ถูกลบในทันที แต่จะทำเครื่องหมายด้วยธงหลุมฝังศพพิเศษเท่านั้น การลบข้อมูลทางกายภาพจะเกิดขึ้นในภายหลัง เมื่อมีการดำเนินการบีบอัดครั้งใหญ่
แอตทริบิวต์ที่อยู่ในกลุ่มคอลัมน์เดียวกันและสอดคล้องกับคีย์เดียวกันจะถูกจัดเก็บทางกายภาพเป็นรายการที่เรียงลำดับ แอตทริบิวต์ใดๆ อาจไม่มีหรือมีอยู่สำหรับแต่ละคีย์ และถ้าไม่มีแอตทริบิวต์ การดำเนินการนี้จะไม่ทำให้เกิดค่าใช้จ่ายในการจัดเก็บค่าว่าง
ชื่อกลุ่มรายการและคอลัมน์ได้รับการแก้ไขและมีเค้าโครงที่ชัดเจน ที่ระดับกลุ่มคอลัมน์ พารามิเตอร์ต่างๆ เช่น time to live (TTL) และจำนวนสูงสุดของเวอร์ชันที่เก็บไว้จะถูกตั้งค่า หากความแตกต่างระหว่างการประทับเวลาสำหรับเวอร์ชันใดเวอร์ชันหนึ่งและเวลาปัจจุบันมากกว่า TTL รายการจะถูกทำเครื่องหมายเพื่อลบ ถ้าจำนวนของเวอร์ชันสำหรับแอตทริบิวต์บางอย่างเกินจำนวนเวอร์ชันสูงสุด เรกคอร์ดจะถูกทำเครื่องหมายเพื่อลบด้วย
![](https://cdn.codegym.cc/images/article/38a31201-f909-4a45-9792-a5d72225f060/512.jpeg)
โมเดลข้อมูล Hbase สามารถจดจำได้ว่าเป็นคีย์-ค่าที่ตรงกัน:
<table, RowKey, Column Family, Column, timestamp> -> Value
6.3 การดำเนินการที่สนับสนุน
รายการการดำเนินการที่รองรับใน hbase นั้นค่อนข้างง่าย รองรับการทำงานหลัก 4 อย่าง:
- ใส่ : เพิ่มรายการใหม่ใน hbase สามารถตั้งค่าการประทับเวลาของรายการนี้ได้ด้วยมือ มิฉะนั้นจะถูกตั้งค่าเป็นเวลาปัจจุบันโดยอัตโนมัติ
- รับ : รับข้อมูลสำหรับ RowKey เฉพาะ คุณสามารถระบุ Column Family ที่เราจะรับข้อมูลและจำนวนรุ่นที่เราต้องการอ่าน
- Scan : อ่านบันทึกทีละรายการ คุณสามารถระบุบันทึกที่เราเริ่มอ่าน บันทึกที่จะอ่าน จำนวนบันทึกที่จะอ่าน ครอบครัวคอลัมน์ที่จะอ่าน และจำนวนเวอร์ชันสูงสุดสำหรับแต่ละบันทึก
- ลบ : ทำเครื่องหมายเวอร์ชันเฉพาะสำหรับการลบ จะไม่มีการลบทางกายภาพ แต่จะเลื่อนออกไปจนกว่าจะมีการบดอัดครั้งใหญ่ครั้งต่อไป (ดูด้านล่าง)
6.4 สถาปัตยกรรม
HBase เป็นฐานข้อมูลแบบกระจายที่สามารถทำงานบนเซิร์ฟเวอร์จริงหลายสิบหรือหลายร้อยเครื่อง ทำให้มั่นใจได้ว่าการทำงานจะไม่หยุดชะงักแม้ว่าบางเซิร์ฟเวอร์จะล้มเหลวก็ตาม ดังนั้นสถาปัตยกรรมของ HBase จึงค่อนข้างซับซ้อนเมื่อเทียบกับฐานข้อมูลเชิงสัมพันธ์แบบคลาสสิก
![](https://cdn.codegym.cc/images/article/5bae086c-b213-47db-be33-a23d854a1543/1024.jpeg)
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![](https://cdn.codegym.cc/images/article/d13e20e1-fed9-444a-929c-15ab43d8209b/800.jpeg)
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
-
Hbase ผสานรวมกับ MapReduce นอกกรอบ และสามารถใช้เป็นอินพุตและเอาต์พุตโดยใช้ TableInputFormat และ TableOutputFormat พิเศษ
-
การเลือก RowKey ที่เหมาะสมเป็นสิ่งสำคัญมาก RowKey ต้องจัดเตรียมการกระจายที่ดีอย่างสม่ำเสมอทั่วทั้งภูมิภาค มิฉะนั้นจะมีความเสี่ยงของสิ่งที่เรียกว่า "ภูมิภาคร้อน" ซึ่งเป็นภูมิภาคที่มีการใช้งานบ่อยกว่าภูมิภาคอื่น ซึ่งนำไปสู่การใช้ทรัพยากรระบบที่ไม่มีประสิทธิภาพ
-
หากไม่ได้อัปโหลดข้อมูลเดี่ยวๆ แต่ทันทีเป็นชุดใหญ่ Hbase รองรับกลไก BulkLoad พิเศษที่ช่วยให้คุณอัปโหลดข้อมูลได้เร็วกว่าการใช้ Puts เดียว BulkLoad เป็นการดำเนินการสองขั้นตอน:
- การก่อตัวของ HFile โดยไม่ต้องมีส่วนร่วมของงาน MapReduce พิเศษ
- การแทรกไฟล์เหล่านี้ลงใน Hbase โดยตรง
-
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 นั้นสมเหตุสมผลเมื่อ:
- มีข้อมูลจำนวนมากและไม่พอดีกับคอมพิวเตอร์ / เซิร์ฟเวอร์เครื่องเดียว
- ข้อมูลมีการปรับปรุงและลบบ่อยครั้ง
- มี "คีย์" ที่ชัดเจนในข้อมูลซึ่งสะดวกในการผูกมัดทุกอย่าง
- ต้องการการประมวลผลเป็นชุด
- ต้องการการเข้าถึงข้อมูลแบบสุ่มด้วยคีย์เฉพาะ