โครงสร้างข้อมูลพื้นฐานที่ใช้สำหรับ Redis คืออะไร


305

ฉันพยายามตอบคำถามสองข้อในรายการสรุป:

  1. โครงสร้างข้อมูลพื้นฐานที่ใช้สำหรับ Redis คืออะไร
  2. และข้อดีข้อเสีย / ข้อเสีย / การใช้งานหลักของแต่ละประเภทคืออะไร?

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

โดยเฉพาะฉันกำลังมองหาร่างทุกประเภท: สตริง, รายการ, ชุด, zset และแฮ

โอ้ฉันได้ดูที่บทความเหล่านี้และอื่น ๆ :


7
วิธีการใช้เซิร์ฟเวอร์เป็นเรื่องไม่สำคัญ? ฉันจะทราบได้อย่างไรว่าจะใช้โครงสร้างการเขียนโปรแกรมหนึ่งเมื่อเทียบกับอีกโครงสร้างหนึ่ง สิ่งนี้ใช้ได้โดยตรงกับการเขียนโปรแกรมเนื่องจากฉันใช้ประเภทที่แตกต่างกันสำหรับการใช้งานที่ต่าง
Homer6

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

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

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

75
@JerryCoffin ด้วยความเคารพ Redis เป็นเครื่องมือในการพัฒนาซอฟต์แวร์และการถามคำถามเกี่ยวกับเครื่องมือในการพัฒนาซอฟต์แวร์นั้นมีความสำคัญในหัวข้อ ความจริงที่ว่า "คุณสามารถรับคำตอบจากแหล่งที่มา" ไม่ใช่เหตุผลที่ปิด ... มันอาจใช้เวลาหลายชั่วโมงกว่าจะได้คำตอบจากแหล่งที่มา และ Redis ใช้กันอย่างแพร่หลายดังนั้นคำถามนี้ไม่ได้แปลเป็ Stack Overflow เป็นข้อมูลเกี่ยวกับการเรียนรู้เกี่ยวกับการเขียนโปรแกรมและถามว่าโครงสร้างข้อมูลใดถูกใช้โดยเครื่องมือการเขียนโปรแกรมที่ได้รับความนิยมอย่างมากซึ่งมีส่วนช่วยในเป้าหมายนั้น ในระยะสั้นฉันไม่พบเหตุผลที่จะปิดคำถามนี้
Joel Spolsky

คำตอบ:


612

ฉันจะพยายามตอบคำถามของคุณ แต่ฉันจะเริ่มต้นด้วยสิ่งที่อาจดูแปลกในตอนแรก: หากคุณไม่สนใจ Redis internals คุณไม่ควรสนใจว่าจะมีการใช้งานข้อมูลภายในชนิดใด นี่คือเหตุผลง่ายๆ: สำหรับการดำเนินการ Redis ทุกครั้งคุณจะพบความซับซ้อนของเวลาในเอกสารประกอบและหากคุณมีชุดปฏิบัติการและความซับซ้อนของเวลาสิ่งอื่น ๆ ที่คุณต้องการคือเงื่อนงำเกี่ยวกับการใช้หน่วยความจำ (และเนื่องจาก เราทำการปรับให้เหมาะสมหลายอย่างซึ่งอาจแตกต่างกันไปขึ้นอยู่กับข้อมูลวิธีที่ดีที่สุดในการรับตัวเลขหลังเหล่านี้กำลังทำการทดสอบในโลกแห่งความจริงเล็กน้อย)

แต่เมื่อคุณถามนี่คือการใช้งานพื้นฐานของ Redis ทุกประเภท

  • มีการใช้งานสตริงโดยใช้ไลบรารีสตริง C ไดนามิกเพื่อให้เราไม่ต้องจ่าย วิธีนี้เรามี O (N) ผนวกตัวอย่างเช่นแทนที่จะมีพฤติกรรมกำลังสอง
  • รายการจะดำเนินการกับรายการที่เชื่อมโยง
  • ชุดและHashesจะดำเนินการกับตารางแฮช
  • ชุดที่เรียงลำดับจะถูกนำไปใช้กับรายการข้าม (ต้นไม้ที่สมดุลเฉพาะประเภท)

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

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

เงื่อนไข

นี่คือประเภทฐานของทุกประเภท มันเป็นหนึ่งในสี่ประเภท แต่ยังเป็นชนิดพื้นฐานของชนิดที่ซับซ้อนเนื่องจาก List คือรายการของสตริงชุด Set เป็นชุดของสตริงและอื่น ๆ

สตริง Redis เป็นความคิดที่ดีในทุกสถานการณ์ที่คุณต้องการเก็บหน้า HTML แต่เมื่อคุณต้องการหลีกเลี่ยงการแปลงข้อมูลที่เข้ารหัสแล้ว ตัวอย่างเช่นหากคุณมี JSON หรือ MessagePack คุณอาจเก็บวัตถุเป็นสตริง ใน Redis 2.6 คุณสามารถจัดการกับฝั่งเซิร์ฟเวอร์วัตถุชนิดนี้โดยใช้สคริปต์ Lua

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

รายการ

รายการจะดีเมื่อคุณมีโอกาสสัมผัสเฉพาะส่วนที่มากที่สุดของรายการ: ใกล้หางหรือใกล้หัว รายการไม่ดีมากในการให้เลขหน้าเนื่องจากการเข้าถึงแบบสุ่มช้า O (N) ดังนั้นการใช้รายการที่ดีก็คือคิวและสแต็กธรรมดาหรือการประมวลผลรายการในลูปโดยใช้ RPOPLPUSH ที่มีแหล่งที่มาและปลายทางเดียวกันเพื่อ "หมุน" วงแหวนของไอเท็ม

รายการก็ยังดีเมื่อเราต้องการเพียงแค่สร้างคอลเลกชันที่ปกคลุมของรายการ N ซึ่งโดยปกติแล้วเราเข้าถึงรายการด้านบนหรือด้านล่างหรือเมื่อ N มีขนาดเล็ก

ชุด

ชุดเป็นชุดข้อมูลที่ไม่มีการเรียงลำดับดังนั้นจึงเป็นชุดที่ดีทุกครั้งที่คุณมีชุดรายการและเป็นสิ่งสำคัญมากที่ต้องตรวจสอบการมีอยู่หรือขนาดของชุดรวบรวมในวิธีที่รวดเร็วมาก อีกสิ่งที่ยอดเยี่ยมเกี่ยวกับชุดคือการสนับสนุนการแอบดูหรือการสุ่มองค์ประกอบ (คำสั่ง SRANDMEMBER และ SPOP)

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

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

ชุดเล็กถูกเข้ารหัสด้วยวิธีที่มีประสิทธิภาพมาก

hashes

แฮชเป็นโครงสร้างข้อมูลที่สมบูรณ์แบบเพื่อแสดงวัตถุประกอบด้วยฟิลด์และค่า เขตข้อมูลของแฮชสามารถเพิ่มค่าแบบอะตอมใช้ HINCRBY เมื่อคุณมีวัตถุเช่นผู้ใช้โพสต์บล็อกหรือรายการประเภทอื่นแฮชอาจเป็นวิธีที่จะไปหากคุณไม่ต้องการใช้การเข้ารหัสของคุณเองเช่น JSON หรือคล้ายกัน

อย่างไรก็ตามโปรดจำไว้ว่าแฮ็กขนาดเล็กนั้นได้รับการเข้ารหัสอย่างมีประสิทธิภาพมากโดย Redis และคุณสามารถขอให้ Redis เป็น GET, SET หรือเพิ่มฟิลด์แต่ละรายการในแบบรวดเร็วมาก

แฮชยังสามารถใช้เพื่อแสดงโครงสร้างข้อมูลที่เชื่อมโยงโดยใช้การอ้างอิง ตัวอย่างเช่นตรวจสอบการใช้ความคิดเห็น lamernews.com

ชุดเรียง

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

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

ชุดที่จัดเรียงนั้นดีสำหรับลำดับความสำคัญของคิว

ชุดที่เรียงเป็นเหมือนรายการที่มีประสิทธิภาพมากกว่าที่การแทรกเอาออกหรือรับช่วงจากตรงกลางของรายการนั้นรวดเร็วเสมอ แต่พวกเขาใช้หน่วยความจำมากขึ้นและเป็นโครงสร้างข้อมูล O (log (N))

ข้อสรุป

ฉันหวังว่าฉันจะให้ข้อมูลบางอย่างในโพสต์นี้ แต่ดีกว่าการดาวน์โหลดซอร์สโค้ดของ lamernews จากhttp://github.com/antirez/lamernewsและเข้าใจวิธีการทำงาน มีการใช้โครงสร้างข้อมูลจำนวนมากจาก Redis ภายใน Lamer News และมีข้อมูลมากมายเกี่ยวกับสิ่งที่จะใช้ในการแก้ปัญหาที่กำหนด

ขออภัยสำหรับความผิดพลาดทางไวยากรณ์มันเที่ยงคืนที่นี่และเหนื่อยเกินกว่าที่จะตรวจสอบโพสต์;)


45
นี่คือผู้เขียนคนเดียวของ Redis ฉันส่งอีเมลถึงเขาและขอให้เขาตอบกลับ ขอบคุณมาก Salvatore มาก ๆ นี่คือข้อมูลที่ดี
Homer6

58
ขอบคุณ แต่ฉันไม่ได้เป็นผู้สนับสนุนใหญ่ แต่เพียงผู้เดียว, ปีเตอร์ Noordhuis จัดให้มีชิ้นส่วนขนาดใหญ่มากของการใช้งานปัจจุบัน :)
antirez

1
หากสตริงที่เหมือนกันอยู่ในชุดที่แตกต่างกันจำนวนมากจะจัดเก็บสำเนาของสตริงเพียงชุดเดียวหรือไม่
sbrian

zscore เป็นอย่างไรใน O (1) โดยใช้รายการข้ามเท่านั้น
Maxime

1
ในขณะที่นัก skiplist ไม่ได้เป็นต้นไม้ที่มีความสมดุลที่เหมาะสมคุณสามารถเห็นนัก skiplist เป็นต้นไม้สุ่ม "กลับ" โดยพื้นฐานแล้วพวกเขาจะค่อนข้างเท่าเทียมกันแม้ว่าการใช้งานและเค้าโครงจะแตกต่างกัน
antirez

80

ส่วนใหญ่คุณไม่จำเป็นต้องเข้าใจโครงสร้างข้อมูลพื้นฐานที่ Redis ใช้ แต่ความรู้เล็ก ๆ น้อย ๆ ช่วยให้คุณลดการใช้หน่วยความจำของ CPU v / s นอกจากนี้ยังช่วยให้คุณจำลองข้อมูลได้อย่างมีประสิทธิภาพ

ภายใน Redis ใช้โครงสร้างข้อมูลต่อไปนี้:

  1. เชือก
  2. พจนานุกรม
  3. รายการที่เชื่อมโยงทวีคูณ
  4. ข้ามรายการ
  5. รายการซิป
  6. ชุด Int
  7. แผนที่ Zip (คัดค้านรายการ zip ตั้งแต่ Redis 2.6)

object encoding <key>เพื่อหาข้อมูลการเข้ารหัสที่ใช้โดยคีย์เฉพาะใช้คำสั่ง

1. เงื่อนไข

ใน Redis, Strings จะเรียกว่าง่ายแบบไดนามิก Strings หรือ SDS มันเป็น wrapper เล็ก ๆchar *ที่ให้คุณเก็บความยาวของสตริงและจำนวนไบต์อิสระเป็นคำนำหน้า

เนื่องจากความยาวของสตริงถูกเก็บไว้strlenจึงเป็นการดำเนินการ O (1) นอกจากนี้เนื่องจากทราบความยาวสตริง Redis จึงปลอดภัยแบบไบนารี มันเป็นกฎหมายที่ดีเลิศสำหรับสตริงจะมีอักขระ null

สตริงเป็นโครงสร้างข้อมูลที่หลากหลายที่สุดที่มีใน Redis สตริงเป็นทั้งหมดต่อไปนี้:

  1. สตริงอักขระที่สามารถเก็บข้อความ ดูคำสั่งSETและGET
  2. อาร์เรย์ไบต์ที่สามารถเก็บข้อมูลไบนารี
  3. A longที่สามารถเก็บหมายเลขได้ ดูที่คำสั่งINCR , DECR , INCRBYและDECRBY
  4. อาร์เรย์ (จากchars, ints, longsหรือชนิดข้อมูลอื่น ๆ ) ที่สามารถช่วยให้เข้าถึงโดยสุ่มที่มีประสิทธิภาพ ดูคำสั่งSETRANGEและGETRANGE
  5. บิตอาที่ช่วยให้คุณสามารถตั้งค่าหรือได้รับแต่ละบิต ดูSETBITและGETBITคำสั่ง
  6. บล็อกของหน่วยความจำที่คุณสามารถใช้เพื่อสร้างโครงสร้างข้อมูลอื่น ๆ สิ่งนี้ถูกใช้ภายในเพื่อสร้าง ziplists และ intsets ซึ่งเป็นโครงสร้างข้อมูลขนาดกะทัดรัดและหน่วยความจำที่มีประสิทธิภาพสำหรับองค์ประกอบจำนวนน้อย เพิ่มเติมเกี่ยวกับเรื่องนี้ด้านล่าง

2. พจนานุกรม

Redis ใช้พจนานุกรมสำหรับสิ่งต่อไปนี้:

  1. ในการจับคู่คีย์กับค่าที่เกี่ยวข้องโดยที่ค่าสามารถเป็นสตริงแฮชเซ็ตชุดเรียงหรือรายการ
  2. ในการจับคู่กุญแจกับเวลาที่หมดอายุ
  3. เมื่อต้องการใช้ Hash, Set และ Sorted Set data types
  4. เมื่อต้องการแมปคำสั่ง Redis กับฟังก์ชันที่จัดการกับคำสั่งเหล่านั้น
  5. เมื่อต้องการแมปคีย์ Redis กับรายการไคลเอนต์ที่ถูกบล็อกบนคีย์นั้น ดูBLPOP

Redis พจนานุกรมจะดำเนินการโดยใช้ตารางแฮช แทนที่จะอธิบายการนำไปใช้ฉันจะอธิบายเฉพาะสิ่งที่ Redis:

  1. พจนานุกรมใช้โครงสร้างที่เรียกว่าdictTypeเพื่อขยายลักษณะการทำงานของตารางแฮช โครงสร้างนี้มีพอยน์เตอร์ของฟังก์ชันและดังนั้นการดำเนินการต่อไปนี้สามารถขยายได้: a) ฟังก์ชันแฮช, b) การเปรียบเทียบคีย์ c) ตัวทำลายคีย์และ d) ตัวทำลายค่า
  2. พจนานุกรมใช้คำพ้องเสียงบ่น 2 (ก่อนหน้านี้พวกเขาใช้ฟังก์ชัน hash djb2โดยมี seed = 5381 แต่จากนั้นฟังก์ชัน hash ถูกเปลี่ยนเป็น murmur2ดูคำถามนี้สำหรับคำอธิบายของอัลกอริทึม hash djb2 )
  3. Redis ใช้ที่เพิ่มขึ้น Hashing ยังเป็นที่รู้จักเพิ่มขึ้นการปรับขนาด พจนานุกรมมีตารางแฮชสองตาราง ทุกครั้งที่สัมผัสกับพจนานุกรมหนึ่งฝากข้อมูลจะถูกย้ายจากตารางแฮชแรก (เล็กกว่า) ไปที่สอง ด้วยวิธีนี้ Redis ช่วยป้องกันการดำเนินการปรับขนาดที่มีราคาแพง

Setโครงสร้างข้อมูลใช้พจนานุกรมเพื่อรับประกันไม่มีซ้ำกัน Sorted Setใช้พจนานุกรมเพื่อแมองค์ประกอบคะแนนของตนซึ่งเป็นเหตุผลที่ZSCOREเป็น O (1) การดำเนินการ

3. รายการที่เชื่อมโยงทวีคูณ

listชนิดข้อมูลจะดำเนินการใช้รายการที่เชื่อมโยงทวีคูณ การใช้งานของ Redis นั้นเป็นแบบตำราตรงๆ การเปลี่ยนแปลงเพียงอย่างเดียวคือ Redis เก็บความยาวในโครงสร้างข้อมูลลิสต์ สิ่งนี้ทำให้มั่นใจได้ว่าLLENมีความซับซ้อน O (1)

4. ข้ามรายการ

Redis ใช้Skip Listsเป็นโครงสร้างข้อมูลพื้นฐานสำหรับชุด Sorted Wikipedia มีการแนะนำที่ดี กระดาษของ William Pugh ข้ามรายการ: ทางเลือกที่น่าจะเป็นกับต้นไม้ที่สมดุลมีรายละเอียดเพิ่มเติม

ชุดที่เรียงใช้ทั้งรายการข้ามและพจนานุกรม พจนานุกรมเก็บคะแนนของแต่ละองค์ประกอบ

การใช้ข้ามรายการของ Redis นั้นแตกต่างจากการใช้มาตรฐานในวิธีต่อไปนี้:

  1. Redis อนุญาตให้ทำซ้ำคะแนน ถ้าสองโหนดมีคะแนนเดียวกันพวกเขาก็จะเรียงตามคำสั่ง lexicographical
  2. แต่ละโหนดมีตัวชี้กลับที่ระดับ 0 ซึ่งช่วยให้คุณสำรวจองค์ประกอบตามลำดับย้อนหลังของคะแนน

5. รายการซิป

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

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

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

รายการซิปใช้เพื่อจัดเก็บรายการขนาดเล็กชุดเรียงและแฮช ชุดที่เรียงลำดับจะถูกทำให้ราบเหมือนรายการที่ต้องการ[element1, score1, element2, score2, element3, score3]และเก็บไว้ในรายการซิป แฮชจะถูกทำให้แบนเหมือนรายการ[key1, value1, key2, value2]ฯลฯ

ด้วยรายการ Zip คุณมีอำนาจในการแลกเปลี่ยนระหว่าง CPU และหน่วยความจำ รายการซิปเป็นหน่วยความจำที่มีประสิทธิภาพ แต่ใช้ CPU มากกว่ารายการที่เชื่อมโยง (หรือตารางแฮช / รายการข้าม) การค้นหาองค์ประกอบในรายการ zip คือ O (n) การแทรกองค์ประกอบใหม่ต้องมีการจัดสรรหน่วยความจำใหม่ ด้วยเหตุนี้ Redis จึงใช้การเข้ารหัสนี้เฉพาะกับรายการขนาดเล็กแฮชและชุดที่เรียงลำดับ คุณสามารถปรับแต่งพฤติกรรมนี้โดยการเปลี่ยนค่าของ<datatype>-max-ziplist-entriesและ<datatype>-max-ziplist-value>ใน redis.conf ดูการเพิ่มประสิทธิภาพหน่วยความจำ Redis ส่วน "การเข้ารหัสพิเศษของชนิดข้อมูลรวมขนาดเล็ก"สำหรับข้อมูลเพิ่มเติม

ความคิดเห็นเกี่ยวกับ ziplist.cที่ยอดเยี่ยมและคุณสามารถเข้าใจโครงสร้างข้อมูลนี้อย่างสมบูรณ์โดยไม่ต้องอ่านรหัส

6. ชุด Int

Int Set เป็นชื่อแฟนซีสำหรับ "Sorted Integer Array"

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

Int Set เป็นอาร์เรย์จำนวนเต็มที่เรียงลำดับแล้ว ในการค้นหาองค์ประกอบจะใช้อัลกอริทึมการค้นหาแบบไบนารี สิ่งนี้มีความซับซ้อนของ O (log N) การเพิ่มจำนวนเต็มใหม่ให้กับอาเรย์นี้อาจต้องทำการจัดสรรหน่วยความจำใหม่ซึ่งอาจมีราคาแพงสำหรับอาร์เรย์จำนวนเต็มขนาดใหญ่

เพื่อเพิ่มประสิทธิภาพหน่วยความจำเพิ่มเติมชุด Int มาใน 3 ตัวแปรที่มีขนาดจำนวนเต็มที่แตกต่างกัน: 16 บิต 32 บิตและ 64 บิต Redis ฉลาดพอที่จะใช้ตัวแปรที่เหมาะสมขึ้นอยู่กับขนาดขององค์ประกอบ เมื่อมีการเพิ่มองค์ประกอบใหม่และมีขนาดเกินกว่าขนาดปัจจุบัน Redis จะย้ายองค์ประกอบไปยังขนาดถัดไปโดยอัตโนมัติ หากมีการเพิ่มสตริง Redis จะแปลง Int Set เป็น Hash Table ตามปกติโดยอัตโนมัติ

ชุด Int เป็นการแลกเปลี่ยนระหว่าง CPU และหน่วยความจำ ชุด Int มีหน่วยความจำที่มีประสิทธิภาพอย่างมากและสำหรับชุดขนาดเล็กจะเร็วกว่าตารางแฮช แต่หลังจากองค์ประกอบจำนวนหนึ่งเวลาเรียกคืน O (log N) และค่าใช้จ่ายในการจัดสรรหน่วยความจำใหม่มากเกินไป จากการทดลองพบว่าเกณฑ์ที่เหมาะสมในการเปลี่ยนไปใช้ตารางแฮชปกติเป็น 512 อย่างไรก็ตามคุณสามารถเพิ่มเกณฑ์นี้ได้ (ลดความไม่เหมาะสม) ตามความต้องการของแอปพลิเคชันของคุณ ดูset-max-intset-entriesใน redis.conf

7. Zip Maps

Zip Maps เป็นพจนานุกรมที่แบนและเก็บไว้ในรายการ มันคล้ายกับรายการซิป

Zip Maps เลิกใช้แล้วตั้งแต่ Redis 2.6 และ hash ขนาดเล็กถูกเก็บไว้ในรายการ Zip ต้องการเรียนรู้เพิ่มเติมเกี่ยวกับการเข้ารหัสนี้อ้างถึงความคิดเห็นใน zipmap.c


2

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

1.strings - ลำดับของไบนารี่เซฟไบต์สูงสุด 512 MB

2.hashes - ชุดของค่าคีย์คู่

3.lists - ชุดของคำสั่งในชุดคำสั่ง

4.sets - ชุดของสตริงที่ไม่ซ้ำกันโดยไม่มีการสั่งซื้อ

5. ชุดสารพัน - ชุดของสตริงที่ไม่ซ้ำกันซึ่งเรียงลำดับตามการให้คะแนนที่ผู้ใช้กำหนด

เงื่อนไข

สตริง Redis เป็นลำดับของไบต์

สตริงใน Redis นั้นปลอดภัยแบบไบนารี (หมายถึงพวกเขามีความยาวที่รู้จักซึ่งไม่ได้พิจารณาจากอักขระที่ยกเลิกพิเศษใด ๆ ) ดังนั้นคุณสามารถเก็บอะไรได้มากถึง 512 เมกะไบต์ในหนึ่งสตริง

Strings เป็นแนวคิด "ที่เก็บค่าคีย์" ของปืนใหญ่ คุณมีคีย์ที่ชี้ไปที่ค่าโดยที่ทั้งคีย์และค่าเป็นข้อความหรือสตริงไบนารี

สำหรับการดำเนินการที่เป็นไปได้ทั้งหมดบนสตริงดูที่ http://redis.io/commands/#string

hashes

แฮช Redis คือชุดของคู่ค่าคีย์

แฮชของ Redis เก็บค่าคีย์ไว้หลายคู่โดยที่แต่ละคีย์และค่าเป็นสตริง แฮช Redis ไม่สนับสนุนค่าที่ซับซ้อนโดยตรง (หมายถึงคุณไม่มีฟิลด์แฮชที่มีค่ารายการหรือชุดหรือแฮชอื่น) แต่คุณสามารถใช้ฟิลด์แฮชเพื่อชี้ไปยังค่าที่ซับซ้อนระดับสูงสุดอื่น ๆ การดำเนินการพิเศษเฉพาะที่คุณสามารถดำเนินการกับค่าของเขตข้อมูลแฮชคือการเพิ่ม / ลดจำนวนอะตอมมิกของเนื้อหาที่เป็นตัวเลข

คุณสามารถนึกถึง Redis hash ได้สองวิธี: เป็นการแทนวัตถุโดยตรงและเป็นวิธีการเก็บค่าเล็ก ๆ มากมายไว้อย่างแน่นหนา

การนำเสนอวัตถุโดยตรงนั้นเข้าใจง่าย วัตถุมีชื่อ (กุญแจของแฮช) และชุดของคีย์ภายในที่มีค่า ดูตัวอย่างด้านล่างสำหรับตัวอย่างที่ดี

การจัดเก็บค่าขนาดเล็กจำนวนมากโดยใช้แฮชเป็นเทคนิคการจัดเก็บข้อมูลขนาดใหญ่อัจฉริยะ เมื่อแฮชมีฟิลด์จำนวนน้อย (~ 100) Redis จะปรับการจัดเก็บและประสิทธิภาพการเข้าถึงของแฮชทั้งหมดให้เหมาะสมที่สุด การเพิ่มประสิทธิภาพการจัดเก็บข้อมูลแฮชขนาดเล็กของ Redis ทำให้เกิดพฤติกรรมที่น่าสนใจ: มีประสิทธิภาพมากกว่าที่จะมี 100 แฮชแต่ละตัวที่มี 100 คีย์ภายในและค่ามากกว่าการมี 10,000 ปุ่มระดับบนสุดที่ชี้ไปที่ค่าสตริง การใช้ Redis hashes เพื่อเพิ่มประสิทธิภาพการจัดเก็บข้อมูลของคุณด้วยวิธีนี้ไม่จำเป็นต้องมีโอเวอร์เฮดการเขียนโปรแกรมเพิ่มเติมสำหรับการติดตามว่าข้อมูลสิ้นสุดลงที่ใด แต่หากการจัดเก็บข้อมูลของคุณเป็นสายอักขระพื้นฐาน

สำหรับการดำเนินการที่เป็นไปได้ทั้งหมดเกี่ยวกับแฮชดูเอกสารแฮ

รายการ

รายการ Redis ทำหน้าที่เหมือนรายการที่เชื่อมโยง

คุณสามารถแทรกลบและข้ามรายการจากส่วนหัวหรือส่วนท้ายของรายการ

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

รายการ Redis มักใช้เป็นคิวผู้ผลิต / ผู้บริโภค แทรกไอเท็มลงในรายการจากนั้นป๊อปไอเท็มจากรายการ จะเกิดอะไรขึ้นหากลูกค้าของคุณพยายามที่จะปรากฏขึ้นจากรายการที่ไม่มีองค์ประกอบ คุณสามารถขอให้ Redis รอให้องค์ประกอบปรากฏและส่งคืนให้คุณได้ทันทีเมื่อมีการเพิ่ม สิ่งนี้จะเปลี่ยน Redis ให้เป็นคิวข้อความเรียลไทม์ / ระบบ / งาน / งาน / ระบบแจ้งเตือน

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

คุณยังสามารถรักษารายการที่มีความยาวคงที่ (คอลเลกชันที่ต่อยอด) โดยการตัดรายการของคุณให้มีขนาดเฉพาะหลังจากการแทรกทุกครั้ง

สำหรับการดำเนินการที่เป็นไปได้ทั้งหมดในรายการให้ดูที่รายการเอกสาร

ชุด

เซต Redis นั้นก็คือเซต

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

ชุดเร็วสำหรับการตรวจสอบการเป็นสมาชิกการแทรกและการลบสมาชิกในชุด

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

ชุดมีการเข้าถึงเวลาอย่างต่อเนื่องสำหรับการตรวจสอบสมาชิก (ไม่เหมือนกับรายการ) และ Redis ยังมีการลบสมาชิกแบบสุ่มและส่งคืนอย่างสะดวก ("ป๊อปองค์ประกอบสุ่มจากชุด") หรือสุ่มสมาชิกกลับโดยไม่มีการแทนที่ ("ให้ฉัน 30 คน ") หรือแทนที่ (" ให้ไพ่ 7 ใบให้ฉัน แต่หลังจากเลือกแล้วให้นำการ์ดกลับมาเพื่อให้สามารถสุ่มตัวอย่างได้อีกครั้ง ")

สำหรับการดำเนินงานที่เป็นไปได้ทั้งหมดในชุดดูชุดเอกสาร

ชุดเรียง

ชุดเรียงที่ Redis เป็นชุดที่มีการสั่งซื้อที่ผู้ใช้กำหนด

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

ชุดที่จัดเรียงยังคงเป็นชุด องค์ประกอบอาจปรากฏเพียงครั้งเดียวในชุด องค์ประกอบสำหรับวัตถุประสงค์ที่ไม่ซ้ำกันถูกกำหนดโดยเนื้อหาสตริง การใส่องค์ประกอบ "แอปเปิ้ล" ด้วยคะแนนการเรียงลำดับ 3 จากนั้นใส่องค์ประกอบ "แอปเปิ้ล" ที่มีคะแนนการเรียง 500 ผลลัพธ์ในองค์ประกอบ "แอปเปิ้ล" หนึ่งองค์ประกอบที่มีการเรียงลำดับคะแนน 500 ในชุดเรียงของคุณ ชุดจะไม่ซ้ำกันโดยยึดตามข้อมูลไม่ใช่คู่ (คะแนน, ข้อมูล)

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

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

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

สำหรับการดำเนินการที่เป็นไปได้ทั้งหมดในชุดที่จัดเรียงให้ดูเอกสารชุดเรียงลำดับ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.