
การพัฒนาแอปพลิเคชันกับ Redis น่าสนุกมาก แต่เหมือนเทคโนโลยีใดๆ ก็มีจุดสำคัญบางประการที่คุณควรจำไว้ขณะออกแบบแอปพลิเคชันที่ base บน Redis หรือ Redis namespace คุณคุ้นเคยกับ relational database development แล้ว แต่ในขณะที่หลาย best practices เดียวกันยังใช้ได้ จงจำไว้ว่า Redis เป็น in-memory database และเป็น (mostly) single-threaded อ่านต่อเพื่อสำรวจ Redis keys best practices
ดังนั้น มี peculiarities (ลักษณะเฉพาะ) หลายอย่างที่คุณควรให้ความสำคัญเมื่อใช้ Redis:
1. ติดตาม keys ของคุณด้วย Redis Namespace
Databases จัดเก็บข้อมูล แต่นักพัฒนาทุกคนอาจ lost track (ลืม/ไม่รู้) เกี่ยวกับข้อมูลบางส่วนที่คุณใส่เข้า Redis นี่เป็นธรรมชาติ เนื่องจาก requirements ของแอปพลิเคชันเปลี่ยนไป หรือคุณเปลี่ยนวิธีจัดเก็บข้อมูล อาจคุณลืม EXPIRE keys บางส่วน หรืออาจ module ของแอปพลิเคชันถูก retire (เลิกใช้งาน)
ไม่ว่ากรณีไหน โอกาสคือ ข้อมูลบางส่วนใน Redis database ของคุณไม่ได้ถูกใช้แล้ว และใช้พื้นที่โดยไม่มีวัตถุประสงค์ Redis's schema-less nature ทำให้ยากมากที่จะทำความเข้าใจ dataset contents ของคุณ เว้นแต่คุณใช้ nomenclature (ระบบการตั้งชื่อ) ที่มั่นคงสำหรับ keys การใช้ proper naming methodology พร้อม Redis namespace สำหรับ keys ของคุณ จะทำให้ housekeeping (การบำรุงรักษา) ฐานข้อมูลของคุณง่ายขึ้นมาก เมื่อคุณ namespace keys ของคุณโดย application หรือ service – convention คือใช้ colon (':') character เพื่อ delimit (แบ่ง) ส่วนของชื่อ key - นี่คือ Redis namespace best practice ด้วยวิธีนี้ คุณจะสามารถระบุพวกเขาได้ง่ายระหว่าง data migration, conversion, deletion, หรือ move Redis namespace & Redis namespace keys ช่วยในการระบุนี้
นอกจาก Redis namespace อีก use case ทั่วไปของ Redis คือเป็น secondary data store สำหรับ "hot" data items ในขณะที่ข้อมูลส่วนใหญ่ถูกเก็บใน database อื่น (เช่น PostgreSQL, MongoDB) ในกรณีเช่นนี้ developers บ่อยครั้งลืมลบข้อมูลจาก Redis เมื่อมันถูกย้ายจาก primary data store ประเภท cross-datastore dependency นี้ต้องการ cascading delete ซึ่งสามารถ implement ได้โดยการเก็บ identifiers ทั้งหมดสำหรับ data item ใดๆ ใน Redis set นี่รับประกันว่า cleanup procedure ที่ invoke หลัง deletion จาก primary data store ต้องแค่ iterate ผ่าน contents ของ set นั้น เพื่อลบ copies ที่เกี่ยวข้องทั้งหมดและ related tidbits (รวมถึง set เองเมื่อเสร็จสิ้น)
2. ติดตามความยาวของ key names
นี่อาจดูขัดแย้งกับข้อข้างต้นเกี่ยวกับ Redis namespace แต่เนื่องจาก key names ก็ใช้ memory เช่นกัน คุณควรพยายามให้สั้นที่สุด ไม่ว่าจะเป็นอย่างไร นี่กลายเป็น issue กับ datasets ที่มี keys หลายล้านหรือหลายพันล้าน แต่ความจริงคือ long keys มีราคากับ hashtable ใดๆ
ตัวอย่าง: พิจารณาว่า storing 1,000,000 keys พร้อม Redis namespace แต่ละตัวตั้งค่า value 32-character จะใช้ memory ประมาณ 96MB เมื่อใช้ 6-character key names และ 111MB กับ 12-character names (บน Redis server 32-bit) overhead มากกว่า 15% นี้กลายเป็น significant ค่อนข้างมากเมื่อจำนวน keys ของคุณเพิ่มขึ้น ด้วย Redis การลบ keys ด้วย prefixes ก็เป็นไปได้
3. ใช้ data structures ที่เหมาะสม
ไม่ว่าจะเพราะ memory usage หรือ performance บางครั้ง data structure หนึ่งเหมาะกับ dataset ของคุณกว่าอีกอัน นี่คือ best practices จำนวนหนึ่งที่ควรจำไว้:
-
แทนที่จะเก็บข้อมูลใน thousands (หรือ millions) ของ independent string values ให้พิจารณา group related data ด้วย hash data structure Hashes มีประสิทธิภาพมาก และสามารถลด memory usage ได้ (บวกกับค่าเพิ่มของการ abstract บางรายละเอียดและทำให้ code อ่านง่ายขึ้น) สำหรับข้อมูลเพิ่มเติมเรื่องนี้ ดูบทความนี้
-
เมื่อ applicable ใช้ lists แทน sets หากคุณไม่ต้องการ properties ของ set สำหรับ ensure uniqueness หรือ checking membership list จะใช้ memory น้อยกว่าและ insert เร็วกว่า
-
Sorted sets เป็น data structure ที่มีค่าใช้จ่ายสูงสุด (most expensive) ทั้งในแง่ memory consumption และ basic operations complexity (เช่น ZADDing a new member) หากคุณแค่ต้องการวิธี lookup scores และ order ไม่สำคัญ พิจารณาใช้ hashes แทน
-
ฟีเจอร์ที่มักถูกมองข้ามใน Redis คือ bitmaps หรือ bitsets (มีตั้งแต่ v2.2) Bitsets อนุญาตให้คุณทำ bit-level operations หลายอย่างบน Redis values ซึ่งอาจหมายถึง storing large amounts of data อย่างมีประสิทธิภาพ สามารถใช้ได้เช่น สำหรับ lightweight analytics บางอย่าง
4. ใช้ SCAN อย่าใช้ KEYS
คำสั่ง SCAN พร้อมใช้งานตั้งแต่ Redis v2.8 และช่วยให้คุณ retrieve keys ใน keyspace โดยใช้ cursor พฤติกรรมนี้แตกต่างจาก (hiss) คำสั่ง KEYS ซึ่ง return all matching elements ทีเดียว แต่ถูกมองว่า risky ใน production เพราะอาจ block Redis server และแม้แต่ exhaust RAM resources SCAN ในทางกลับกัน ทำให้ inspect data ได้โดยไม่มีความเสี่ยง block server หรือต้องพึ่ง slave
โปรดสังเกตว่า SCAN ต้องการให้คุณอ่าน cursor value ที่ส่งไป subsequent call ถัดไปของ SCAN SCAN ยัง accept keyname pattern และ optional count argument อีกความแตกต่างระหว่าง SCAN และ KEYS คือ อาจได้ key name เดียวกันมากกว่าหนึ่งครั้งกับ SCAN
SCAN มาพร้อมกับ SSCAN, HSCAN, และ ZSCAN ซึ่งช่วยให้คุณ iterate contents ของ sets, hashes, และ sorted sets (ตามลำดับ)
5. ใช้ Server-Side Lua Scripts
ในฐานะ developer คุณจะเดินบนพื้นที่คุ้นเคยเมื่อคุณยอมรับความสามารถของ Redis ในการ run Lua scripts หนึ่งในภาษาที่ง่ายที่สุดในการเรียน Lua ให้คุณความสามารถในการ express ความคิดสร้างสรรค์ของคุณด้วย code ที่รันภายใน Redis server เอง เมื่อใช้ได้ถูกต้อง Lua scripts สามารถทำความแตกต่างอย่างมากในแง่ performance และ resource consumption แทนที่จะนำ data ไปที่ (application's) CPU scripts อนุญาตให้คุณ execute logic ใกล้ data ซึ่งลด network latency และ redundant transmission ของ data
ตัวอย่างคลาสสิกของ Lua's dramatic impact เกิดขึ้นเมื่อคุณ fetch ข้อมูลเยอะจาก Redis เพื่อแค่ filter หรือ aggregate ใน application ของคุณ โดยการ encapsulate processing workflow ใน script คุณแค่ต้อง invoke มัน เพื่อได้ significantly smaller answer ใน fraction ของเวลาและทรัพยากร
Pro Tip: Lua ดีมาก แต่เมื่อคุณย้าย workflows ไปที่มัน คุณอาจพบว่า error reporting และ handling ยากกว่า (คุณรันอยู่ภายใน Redis server จริงๆ) หนึ่งวิธีฉลาดคือใช้ Redis' Pub/Sub และให้ scripts publish "log" messages ไป dedicated channel จากนั้น setup subscriber process เพื่อรับ messages นี้และ handle ตามที่เหมาะสม
อาจมี tips สำคัญอื่นๆ มากมายที่คุณจะคิดค้นระหว่าง Redis escapades ของคุณ แต่ list นี้ควรช่วยให้เริ่มต้นกับบางอย่างที่สำคัญที่สุด หากคุณมี suggestions อื่นๆ ที่อยากแชร์ feedback หรือ questions – โปรดรู้สึกสบายใจ shout หาผมได้ ผม highly available 🙂