ฉันรู้ว่าทั้งสองดำเนินการในคอลัมน์ในตาราง แต่วิธีการดำเนินการแต่ละอย่างแตกต่างกันอย่างไร
ฉันรู้ว่าทั้งสองดำเนินการในคอลัมน์ในตาราง แต่วิธีการดำเนินการแต่ละอย่างแตกต่างกันอย่างไร
คำตอบ:
ข้อมูลการแบ่งพาร์ทิชันมักใช้สำหรับการกระจายโหลดในแนวนอนซึ่งมีประโยชน์ด้านประสิทธิภาพและช่วยในการจัดระเบียบข้อมูลในแบบตรรกะ ตัวอย่าง : หากเรากำลังเผชิญกับemployee
ตารางที่มีขนาดใหญ่และมักเรียกใช้คิวรีที่มีWHERE
คำสั่งที่ จำกัด ผลลัพธ์ให้เฉพาะประเทศหรือแผนก สำหรับการตอบสนองได้เร็วขึ้นแบบสอบถามตาราง Hive PARTITIONED BY (country STRING, DEPT STRING)
สามารถ ตารางการแบ่งพาร์ติชันจะเปลี่ยนวิธีที่โครงสร้างของไฮฟ์ที่จัดเก็บข้อมูลและไฮฟ์จะสร้างไดเรกทอรีย่อยที่สะท้อนโครงสร้างการแบ่งพาร์ติชันได้อย่างไร
... / พนักงาน / ประเทศ = ABC / DEPT = XYZ
หากข้อ จำกัด การสืบค้นสำหรับพนักงานcountry=ABC
มันจะสแกนเนื้อหาของไดเรกทอรีเดียวcountry=ABC
เท่านั้น สิ่งนี้สามารถปรับปรุงประสิทธิภาพการสืบค้นได้อย่างมาก แต่เฉพาะเมื่อโครงร่างการแบ่งพาร์ติชันสะท้อนการกรองทั่วไป คุณลักษณะการแบ่งพาร์ติชันมีประโยชน์มากใน Hive อย่างไรก็ตามการออกแบบที่สร้างพาร์ติชันมากเกินไปอาจปรับให้เหมาะสมกับแบบสอบถามบางอย่าง แต่เป็นอันตรายสำหรับการค้นหาที่สำคัญอื่น ๆ ข้อเสียอื่น ๆ ที่มีพาร์ติชันมากเกินไปคือไฟล์และไดเรกทอรี Hadoop จำนวนมากที่สร้างขึ้นโดยไม่จำเป็นและโอเวอร์เฮดไปที่ NameNode เนื่องจากจะต้องเก็บข้อมูลเมตาทั้งหมดสำหรับระบบไฟล์ในหน่วยความจำ
การทิ้งเป็นอีกเทคนิคหนึ่งสำหรับการแยกย่อยชุดข้อมูลออกเป็นส่วนที่จัดการได้มากขึ้น ตัวอย่างเช่นสมมติว่าตารางที่ใช้date
เป็นพาร์ติชันระดับบนสุดและemployee_id
เนื่องจากพาร์ติชันระดับที่สองนำไปสู่พาร์ติชันขนาดเล็กจำนวนมากเกินไป แต่ถ้าเราฝากข้อมูลตารางพนักงานและใช้employee_id
เป็นคอลัมน์การบันทึกค่าของคอลัมน์นี้จะถูกแฮชโดยจำนวนที่ผู้ใช้กำหนดลงในที่เก็บข้อมูล บันทึกที่เหมือนกันemployee_id
จะถูกเก็บไว้ในที่เก็บข้อมูลเดียวกันเสมอ สมมติว่าจำนวนemployee_id
มากขึ้นกว่าจำนวนของถัง, employee_id
ถังแต่ละคนจะมีจำนวนมาก ในขณะที่สร้างตารางคุณสามารถระบุเช่นCLUSTERED BY (employee_id) INTO XX BUCKETS;
โดยที่ XX คือจำนวนของถัง การฝากเงินมีข้อดีหลายประการ จำนวนของถังได้รับการแก้ไขดังนั้นจึงไม่ผันผวนกับข้อมูล หากสองตารางถูกฝากข้อมูลโดยemployee_id
Hive สามารถสร้างการสุ่มตัวอย่างที่ถูกต้องตามหลักเหตุผล การใช้ Bucketing ช่วยในการทำแผนที่เข้าด้วยกันอย่างมีประสิทธิภาพเป็นต้น
มีรายละเอียดบางส่วนหายไปจากคำอธิบายก่อนหน้า เพื่อให้เข้าใจได้ดีขึ้นว่าการแบ่งพาร์ติชันและการเก็บรักษาทำงานอย่างไรคุณควรดูว่าข้อมูลถูกเก็บไว้ในรังอย่างไร สมมติว่าคุณมีโต๊ะ
CREATE TABLE mytable (
name string,
city string,
employee_id int )
PARTITIONED BY (year STRING, month STRING, day STRING)
CLUSTERED BY (employee_id) INTO 256 BUCKETS
จากนั้นไฮฟ์จะจัดเก็บข้อมูลในลำดับชั้นไดเรกทอรีเช่น
/user/hive/warehouse/mytable/y=2015/m=12/d=02
ดังนั้นคุณต้องระวังเมื่อทำการแบ่งพาร์ติชันเพราะถ้าคุณใช้พาร์ทิชันอินสแตนซ์โดย employee_id และคุณมีพนักงานนับล้านคนคุณจะต้องมีไดเรกทอรีนับล้านในระบบไฟล์ของคุณ คำว่า ' cardinality ' หมายถึงจำนวนค่าที่เป็นไปได้ที่ฟิลด์สามารถมีได้ ตัวอย่างเช่นหากคุณมีเขตข้อมูล 'ประเทศ' ประเทศในโลกจะมีประมาณ 300 แห่งดังนั้นความเป็นจริงของ cardinality คือ ~ 300 สำหรับเขตข้อมูลเช่น 'timestamp_ms' ซึ่งเปลี่ยนแปลงทุก ๆ มิลลิวินาที cardinality อาจเป็นพันล้าน โดยทั่วไปเมื่อเลือกเขตข้อมูลสำหรับการแบ่งพาร์ติชันมันไม่ควรมีความสำคัญสูงเนื่องจากคุณจะมีไดเรกทอรีจำนวนมากในระบบไฟล์ของคุณ
การทำคลัสเตอร์อาคาการจัดกลุ่มในทางกลับกันจะส่งผลให้มีจำนวนไฟล์คงที่เนื่องจากคุณระบุจำนวนที่เก็บข้อมูล สิ่งที่กลุ่มจะทำคือนำฟิลด์คำนวณแฮชและกำหนดระเบียนให้กับที่ฝากข้อมูล แต่จะเกิดอะไรขึ้นถ้าคุณใช้สมมติว่าถังที่ 256 และเขตข้อมูลที่คุณกำลังไล่ล่ามีความสำคัญต่ำ (เช่นเป็นรัฐของสหรัฐอเมริกาดังนั้นค่าที่ต่างกันเพียง 50 ค่า) คุณจะมี 50 ถังที่มีข้อมูลและ 206 ถังที่ไม่มีข้อมูล
มีคนพูดถึงแล้วว่าพาร์ติชันสามารถลดจำนวนข้อมูลที่คุณสอบถามได้อย่างมาก ดังนั้นในตารางตัวอย่างของฉันถ้าคุณต้องการสอบถามเฉพาะจากวันที่ล่วงหน้าส่งต่อการแบ่งพาร์ติชันตามปี / เดือน / วันจะลดจำนวน IO อย่างมาก ฉันคิดว่ามีบางคนพูดถึงวิธีที่การเพิ่มความเร็วในการเข้าร่วมกับตารางอื่น ๆที่มีการสร้างรายได้เหมือนกันดังนั้นในตัวอย่างของฉันถ้าคุณเข้าร่วมสองตารางใน Employee_id เดียวกันกลุ่มสามารถทำการรวมกลุ่มด้วย bucket ได้ดียิ่งขึ้น ถ้าพวกเขาถูกเรียงลำดับโดย employee_id เนื่องจากมันจะรวมส่วนต่าง ๆ ที่เรียงลำดับแล้วซึ่งทำงานในเวลาเชิงเส้น aka O (n)
ดังนั้นการเลือกถังจะทำงานได้ดีเมื่อเขตข้อมูลมีความสำคัญเชิงสูงและมีการกระจายข้อมูลอย่างเท่าเทียมกันในที่เก็บข้อมูล การแบ่งพาร์ทิชันจะดีที่สุดเมื่อความสำคัญของการแบ่งพาร์ติชันไม่สูงเกินไป
นอกจากนี้คุณสามารถแบ่งพาร์ติชันในหลายเขตข้อมูลที่มีการสั่งซื้อ (ปี / เดือน / วันเป็นตัวอย่างที่ดี) ในขณะที่คุณสามารถ Bucket ในเพียงหนึ่งฟิลด์
ฉันคิดว่าฉันมาตอบคำถามนี้ไม่ทันเวลา แต่มันก็ปรากฏขึ้นในฟีดของฉัน
Navneet ได้ให้คำตอบที่ยอดเยี่ยม เพิ่มไปยังสายตา
การแบ่งพาร์ติชันช่วยในการกำจัดข้อมูลหากใช้ใน WHERE clause ซึ่งการใช้การจัดเก็บช่วยในการจัดระเบียบข้อมูลในแต่ละพาร์ติชันเป็นหลายไฟล์ดังนั้นชุดข้อมูลเดียวกันจะถูกเขียนในถังเดียวกันเสมอ ช่วยในการเข้าร่วมคอลัมน์
สมมติว่าคุณมีตารางที่มีห้าคอลัมน์ชื่อ server_date, some_col3, some_col4 และ some_col5 สมมติว่าคุณได้แบ่งพาร์ติชันตารางบนserver_dateและฝากข้อมูลในคอลัมน์ชื่อใน 10 ถังโครงสร้างไฟล์ของคุณจะมีลักษณะดังนี้
ที่นี่server_date = xyzเป็นพาร์ติชั่นและ000ไฟล์เป็นที่เก็บข้อมูลในแต่ละพาร์ติชั่น ที่ฝากข้อมูลจะถูกคำนวณตามฟังก์ชันแฮชดังนั้นแถวที่มีชื่อ = แซนดี้จะอยู่ในที่เก็บข้อมูลเดียวกันเสมอ
การแบ่งพาร์ติชัน Hive:
พาร์ติชันแบ่งข้อมูลจำนวนมากออกเป็นหลายส่วนโดยอิงตามค่าของคอลัมน์ตาราง
สมมติว่าคุณกำลังเก็บข้อมูลของผู้คนทั่วโลกกระจายอยู่ในกว่า 196 ประเทศครอบคลุมกว่า 500 ล้านรายการ หากคุณต้องการสอบถามผู้คนจากประเทศใดประเทศหนึ่ง (เมืองวาติกัน) หากไม่มีการแบ่งพาร์ติชันคุณจะต้องสแกนรายการทั้งหมด 500 ล้านรายการเพื่อเรียกรายการนับพันรายการของประเทศ หากคุณแบ่งตารางตามประเทศคุณสามารถปรับกระบวนการสืบค้นได้อย่างละเอียดโดยตรวจสอบข้อมูลสำหรับพาร์ติชั่นประเทศเดียวเท่านั้น พาร์ติชันไฮฟ์สร้างไดเรกทอรีแยกต่างหากสำหรับค่าคอลัมน์
ข้อดี:
จุดด้อย:
รังผึ้ง:
การฝากข้อมูลย่อยสลายข้อมูลเป็นส่วนที่จัดการได้หรือเท่าเทียมกันมากขึ้น
ด้วยการแบ่งพาร์ติชันมีความเป็นไปได้ที่คุณสามารถสร้างพาร์ติชันเล็ก ๆ หลายพาร์ติชันตามค่าคอลัมน์ หากคุณไปเพื่อการฝากข้อมูลคุณกำลัง จำกัด จำนวนที่เก็บข้อมูลเพื่อเก็บข้อมูล หมายเลขนี้ถูกกำหนดระหว่างสคริปต์การสร้างตาราง
ข้อดี
จุดด้อย
ก่อนที่จะเข้าไปBucketing
เราต้องเข้าใจสิ่งที่Partitioning
เป็น ให้เราใช้ตารางด้านล่างเป็นตัวอย่าง โปรดทราบว่าฉันได้รับเพียง 12 บันทึกในตัวอย่างด้านล่างเพื่อความเข้าใจในระดับเริ่มต้น ในสถานการณ์ตามเวลาจริงคุณอาจมีบันทึกนับล้าน
การจัดพาร์ติชัน
---------------------
Partitioning
ใช้เพื่อให้ได้ประสิทธิภาพขณะทำการสอบถามข้อมูล ตัวอย่างเช่นในตารางข้างต้นถ้าเราเขียน sql ด้านล่างจะต้องสแกนระเบียนทั้งหมดในตารางซึ่งจะช่วยลดประสิทธิภาพและเพิ่มค่าใช้จ่าย
select * from sales_table where product_id='P1'
เพื่อหลีกเลี่ยงการสแกนแบบเต็มตารางและอ่านเฉพาะระเบียนที่เกี่ยวข้องกับproduct_id='P1'
เราสามารถแบ่งพาร์ติชัน (แยกไฟล์ของตารางไฮฟ์) ออกเป็นหลายไฟล์ตามproduct_id
คอลัมน์ ตามนี้ไฟล์ตารางรังจะถูกแบ่งออกเป็นสองไฟล์หนึ่งที่มีproduct_id='P1'
และอื่น ๆ product_id='P2'
ที่มี ตอนนี้เมื่อเราประมวลผลแบบสอบถามข้างต้นมันจะสแกนเฉพาะproduct_id='P1'
ไฟล์
../hive/warehouse/sales_table/product_id=P1
../hive/warehouse/sales_table/product_id=P2
ไวยากรณ์สำหรับการสร้างพาร์ติชันได้รับด้านล่าง โปรดทราบว่าเราไม่ควรใช้product_id
คำนิยามคอลัมน์พร้อมกับคอลัมน์ที่ไม่ได้แบ่งพาร์ติชันในไวยากรณ์ด้านล่าง สิ่งนี้ควรอยู่ในpartitioned by
ข้อเท่านั้น
create table sales_table(sales_id int,trans_date date, amount int)
partitioned by (product_id varchar(10))
ข้อด้อย : เราควรระมัดระวังในขณะทำการแบ่ง นั่นคือมันไม่ควรใช้สำหรับคอลัมน์ที่จำนวนของค่าการทำซ้ำคือ (คอลัมน์ที่สำคัญโดยเฉพาะอย่างยิ่งหลัก) Name node
น้อยมากเป็นมันจะเพิ่มจำนวนของไฟล์แบ่งพาร์ติชันและเพิ่มค่าใช้จ่ายสำหรับ
BUCKETING
------------------
Bucketing
ใช้เพื่อเอาชนะส่วนcons
ที่ฉันกล่าวถึงในส่วนการแบ่งพาร์ติชัน ควรใช้สิ่งนี้เมื่อมีค่าการทำซ้ำในคอลัมน์น้อยมาก (ตัวอย่าง - คอลัมน์คีย์หลัก) สิ่งนี้คล้ายกับแนวคิดของดัชนีในคอลัมน์คีย์หลักใน RDBMS ในตารางของเราเราสามารถนำSales_Id
คอลัมน์สำหรับการจองตั๋ว มันจะมีประโยชน์เมื่อเราต้องการสอบถามsales_id
คอลัมน์
ด้านล่างเป็นไวยากรณ์สำหรับการฝากข้อมูล
create table sales_table(sales_id int,trans_date date, amount int)
partitioned by (product_id varchar(10)) Clustered by(Sales_Id) into 3 buckets
ที่นี่เราจะแบ่งข้อมูลออกเป็นไฟล์เพิ่มเติมอีกสองสามไฟล์ที่ด้านบนของพาร์ติชัน
เนื่องจากเรามีระบุ3
บุ้งกี๋ก็ถูกแบ่งออกเป็น 3 product_id
ไฟล์แต่ละสำหรับแต่ละ ภายในใช้modulo operator
เพื่อกำหนดว่าsales_id
ควรเก็บถังแต่ละอันไว้ที่ใด ตัวอย่างเช่นสำหรับไฟล์product_id='P1'
the sales_id=1
จะถูกเก็บไว้ในไฟล์000001_0 (เช่น 1% 3 = 1) sales_id=2
จะถูกเก็บไว้ในไฟล์000002_0 (เช่น 2% 3 = 2) sales_id=3
จะถูกเก็บไว้ในไฟล์000000_0 (เช่น 3% 3 = 0) เป็นต้น
hashCode()
ของสตริงเป็นฟังก์ชันแฮชหรือไม่ โปรแกรมเมอร์สามารถเลือกฟังก์ชั่นแฮชได้หรือไม่?
ความแตกต่างคือการbucketingแบ่งไฟล์ตามชื่อคอลัมน์และการแบ่งพาร์ติชันแบ่งไฟล์ภายใต้ตามค่าเฉพาะภายในตาราง
หวังว่าฉันจะกำหนดไว้อย่างถูกต้อง
มีคำตอบที่ดีที่นี่ ฉันต้องการให้มันสั้นเพื่อจดจำความแตกต่างระหว่างพาร์ติชันและที่เก็บข้อมูล
โดยทั่วไปคุณแบ่งพาร์ติชันในคอลัมน์ที่ไม่ซ้ำกันน้อยลง และ bucketing ในคอลัมน์ที่ไม่ซ้ำกันมากที่สุด
ตัวอย่างถ้าคุณพิจารณาประชากรโลกด้วยประเทศชื่อบุคคลและรหัสไบโอเมตริกของพวกเขาเป็นตัวอย่าง อย่างที่คุณสามารถคาดเดาได้ฟิลด์ประเทศจะเป็นคอลัมน์ที่ไม่ซ้ำกันและรหัสไบโอเมตริกจะเป็นคอลัมน์ที่ไม่ซ้ำกันมากที่สุด ดังนั้นคุณจะต้องแบ่งพาร์ทิชันตารางตามประเทศและฝากข้อมูลด้วยรหัสไบโอเมตริก
การใช้พาร์ทิชันในตาราง Hive ขอแนะนำอย่างยิ่งด้วยเหตุผลด้านล่าง -
ตัวอย่าง: -
สมมติว่า Input File (100 GB) ถูกโหลดลงใน temp-hive-table และมีข้อมูลธนาคารจากทั่วภูมิภาคต่างๆ
ตารางไฮฟ์โดยไม่มีการแบ่งพาร์ติชัน
Insert into Hive table Select * from temp-hive-table
/hive-table-path/part-00000-1 (part size ~ hdfs block size)
/hive-table-path/part-00000-2
....
/hive-table-path/part-00000-n
ปัญหาเกี่ยวกับวิธีการนี้คือ - มันจะสแกนข้อมูลทั้งหมดสำหรับการสืบค้นใด ๆ ที่คุณเรียกใช้บนตารางนี้ เวลาตอบสนองจะสูงเมื่อเปรียบเทียบกับวิธีการอื่น ๆ ที่ใช้การแบ่งพาร์ติชันและการ Bucketing
ตารางไฮฟ์กับพาร์ติชัน
Insert into Hive table partition(country) Select * from temp-hive-table
/hive-table-path/country=US/part-00000-1 (file size ~ 10 GB)
/hive-table-path/country=Canada/part-00000-2 (file size ~ 20 GB)
....
/hive-table-path/country=UK/part-00000-n (file size ~ 5 GB)
ข้อดี - ที่นี่หนึ่งสามารถเข้าถึงข้อมูลได้เร็วขึ้นเมื่อมันมาถึงการสืบค้นข้อมูลสำหรับการทำธุรกรรมทางภูมิศาสตร์ที่เฉพาะเจาะจง ข้อด้อย - ข้อมูลการแทรก / การสืบค้นสามารถปรับปรุงได้โดยการแยกข้อมูลภายในแต่ละพาร์ติชัน ดูตัวเลือกการฝากเงินด้านล่าง
ตาราง Hive พร้อม Partition และ Bucketing
หมายเหตุ: สร้างตารางไฮฟ์ ..... ด้วย "CLUSTERED BY (Partiton_Column) เป็น 5 ที่เก็บข้อมูล
Insert into Hive table partition(country) Select * from temp-hive-table
/hive-table-path/country=US/part-00000-1 (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-2 (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-3 (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-4 (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-5 (file size ~ 2 GB)
/hive-table-path/country=Canada/part-00000-1 (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-2 (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-3 (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-4 (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-5 (file size ~ 4 GB)
....
/hive-table-path/country=UK/part-00000-1 (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-2 (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-3 (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-4 (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-5 (file size ~ 1 GB)
ข้อดี - แทรกได้เร็วขึ้น ข้อความค้นหาที่เร็วขึ้น
ข้อด้อย - การเลือกจะสร้างไฟล์เพิ่มเติม อาจมีปัญหากับไฟล์ขนาดเล็กจำนวนมากในบางกรณี
หวังว่านี่จะช่วยได้ !!