Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> ฐานข้อมูล

เพิ่มประสิทธิภาพ Redis ให้สูงสุด: Insights และ Best Practices จากผู้เชี่ยวชาญ

จากการพูดคุยกับหลายคนและบริษัทที่ใช้ Redis ใน Use Cases หลากหลาย ตั้งแต่ Simple Caching ถึง Multi-terabyte Setups หนึ่ง Topic ที่ถูกถามมากที่สุดคือ Performance Redis แตกต่างในการ Approach Performance ใน Database Servers หลายตัว (ถ้ามากกว่า) พยายาม Improve Performance แต่ Redis เป้าหมายคือ "อย่าทำให้มันช้า" (Don't slow it down) Approach นี้ต่างออกไป และต้องใช้ Mindset ต่างออกไปเพื่อเปรียบ

Performance Metrics — Latency เป็นกษัตริย์?

มี 2 Performance Metrics หลักสำหรับ Redis: Commands (หรือ Transactions) ต่อวินาทีได้กี่อัน และ ใช้เวลานานแค่ไหน แบบแยกแล้วพบว่าตัวแรกเป็น Secondary Result จากตัวที่สอง เนื่องจาก Redis เป็น Single-threaded จำนวน Ops/sec ที่ Push ได้ ผูกมัดกับเวลาที่ใช้ ดังนั้นสิ่งที่สำคัญที่สุดคือ "Command Latency"

ข้อดีของ Redis คือ Simplicity เรา Issue Commands ไม่ใช่ Queries Commands เป็นเส้นทางง่ายกว่าในการดึง Data และในกรณีนี้ Simplicity สะท้อนใน Speed ของ Commands ยังช่วยให้ Developers ให้ Optimized Commands แทนที่จะ Optimize สำหรับ Various Queries Simply elegance นี้มอบให้ Programmers ที่ Consume Redis มักหมายถึงการทำ "Query-type Operations" เช่น Filtering a Set ฝั่ง Client แทนที่จะให้ Server Software ทำ

บางคนรู้สึก Query ประเภทนี้ควรทำฝั่ง Server แบบ Consistent แต่ผมเชื่อว่านี่ไม่ใช่ Preferred Route อีกต่อไป เหตุผลคือ Bugbear ที่เรียกว่า "Scalability" เริ่ม Run "Horizontally Scalable" Web Service/Site จะพบว่า Pattern นี้ใช้ได้ดีตอนแรก แต่เมื่อ Handle "Obscene" Levels ของ Traffic จะเรียนรู้ว่า Database เป็น Significant Bottleneck และ Database นี้ (มักเป็น SQL Store เช่น MySQL) ไม่ได้ "Horizontally Scalable" เพิ่ม Instance ไม่ได้ง่ายๆ

Command Latency

Redis ก็ไม่ Horizontally Scalable เหมือนกัน แต่ความต่างคือ การเก็บ Filtering Logic, Sorting และสิ่งที่ Execute ใน Single Redis Command หรือสูงสุดไม่กี่ Commands ไม่ได้ Load DB Down ด้วย Logic — และดังนั้น "Things to Process" Redis ควรใช้เป็น "Data Store" ไม่ใช่ Traditional "Database Server" นี่คือ Aspect แรกของ "Don't Slow Redis Down" ที่ต้องเข้าใจ (Grok) ไม่ควรต้องบอกว่า Lua Scripting รีบร้อนมี Risk Net Lower Performance อาจไม่เห็นตอน Dev (Traffic Low-Moderate) แต่ Large Scales จะเห็น และตอนนั้น Logic Baked In แล้ว กลายเป็น Heavy Technical Debt ย้ายไป Application Code เรารู้กันว่าความสำคัญของ Technical Debt ต่ำแค่ไหน

ไม่ใช่ว่า Lua Scripting ไม่มีที่อยู่ มันหมายถึงต้อง Scrutinize อย่างเข้มงวด Rule of Thumb: เปรียบเทียบ Cost ของ Additional Round Trips หาก Handle Logic Client-side ไม่ใช่ว่า Client Code ทำนานแค่ไหน ถ้า Reduce Round Trip Cost 2ms แต่ Add 3ms Script Execution Time ผิดทางแล้ว

ต้องระมัดข้าว Single-threaded Server นั่น 3ms Script Blocking Potentially Hundreds/Thousands ของ Commands ระหว่าง Execute หาก Split เป็น (Pull) -> (Logic) -> (Pull) Server Process Additional Requests ระหว่าง "(Logic)" Phases เก็บ Logic ไว้ Client Code Preserve Concurrency Inherent ใน Multi-client System หากต้องการ Transactions หรือ Lua Scripting ใช้ได้ แต่อย่าใช้เพราะ Cover "Easier" Code แล้วต้อง Aware Concurrency Performance Hit, Measure, Choose Consciously

นี่นำไปสู่ Rule ที่ 2: Preserve Concurrency โดยหลีกเลี่ยง Server Logic ผ่าน Scripts Side Benefit: Migrate ไป Redis Cluster Setup ได้โดยไม่ Rewrite/Dump Lua Scripts ที่ Operate บน Multiple Keys

Ways อื่นที่ Redis ถูกช้าได้

มี System-level/Operational Aspects ที่ช้า Redis ได้ เหมือน Server อื่น I/O Resource Limits ช้า Redis ได้ ตัวอย่าง: ต้องการ 8GB Network Bandwidth แต่มี 1GB = "Slow" ถ้า Daemon Process Limited Open Sockets น้อยกว่า Concurrent Connections ที่ต้องการ Time จะเสียไปรอ Connections Close แทน Execute Commands

2 Operational Choices ที่พบบ่อยที่สุดทำให้ Redis ช้า: 1) วางบน VM — โดยเฉพาะ Xen Hypervisor และ 2) Heavy Disk Persistence

ข้อแรก Redis Literature แนะนำชัดเจน: อย่าวางบน Xen Hypervisor VM ข้อสอง Persistence ดูเหมือนแนะนำแล้วแต่ในมุมมองผม ไปไม่พอ

มี Standard Recommendations: ใช้ Local Fast Disk, Ensure Memory พอสำหรับ CoW Dance ระหว่าง Persist — แม้แต่ Run Persistence บน Slaves Only สิ่งเหล่านี้ Ripple Through ไป Command Latency ได้ สิ่งที่ขาดคือ How to Properly Determine ว่ามันช้าจริงหรือไม่

Standard Way ทดสอบ: ใช้ Built-in Latency Testing ก่อนจะ Technical Details อยาก Address "How" Question ก่อน Subset หลัก: When To Run Tests ก่อนอื่น Test นี้ meaningless หาก Dataset เล็ก เล็กแค่ไหน? ดูว่า Dump Data to Disk ใช้เวลานานแค่ไหน ถ้าพูดถึง 1-2 วินาที หรือ 10 วินาที Less Likely ได้ Meaningful Data ทั้งนี้ Predicated บน BGSAVE ไม่ใช่ SAVE

Persistence Latency

นี่คือ Principle แรกของ "Persistence Latency" — เวลาจาก Command Hit Server ถึง Result Hit Persistence: หา Persistence Option ที่ Introduce Latency น้อยที่สุด ขึ้นอยู่กับ Network และ Disk AoF หรือ Slave Server จะเป็น Lowest Latency Bumping Option RDB มาสุดท้าย

RDB มาสุดท้ายเพราะมี Built-in Delay N Changes over T Seconds สมมติมี Changes พอใน Minimal Duration (Smallest Default Window 60s) Persistence Delay = Interval T + Time to Write RDB to Disk ถ้า Dump Memory to Disk ใช้ 30s ด้วย Default 60s Interval "Persistence Latency" = (60+30) 90 Seconds

แต่ Begs Question: Persistence Latency นี้เป็น Problem ไหม? 2 Aspects: 1) Sufficient สำหรับ Business Requirements? 2) มันช้า Redis จริงไหม?

ข้อ 1 ไม่มี Generic Answer ตอบทุกคน แต่ถ้า Requirements Tighter Than Formula ข้างบน คำตอบ Trend ไป "Use Slave และ/หรือ AoF" แทน RDB สมมติไม่ทำ Obvious Mistakes บน Platform ที่ Run Redis ซึ่งนำไปสู่ Aspect ที่ 2: มันช้า Redis จริงไหม?

บางคน "ใช้เวลานานแค่ไหน Save RDB File" เป็น Paramount ในความคิด ผมมองว่า Mistake คำถามคือ "Save ช้า Redis ไหม?" ถ้าไม่ ช่วยไม่สนใจว่า 1 Second หรือ 1 Hour ตัวอย่าง Server A Save RDB 1000s ระหว่างไม่ Save Intrinsic Command Latency Range 30-100 Microseconds ระหว่าง Save Latency ยัง 30-100us Range กรณีนี้ Premature Optimization ถ้าลด RDB Save Time ภายใต้ Notion ว่า Poor Redis Performance

แต่ Server B Save 10s แต Command Latency Jump จาก 30-100us เป็น 130-250us ตอนนี้มีเหตุผลกังวลเรื่อง RDB Save Time เพราะ Save ช้า Redis และอยาก Minimize นั้น หากหมายถึง Faster Disks ตอนนี้ Justify ได้ — สมมติ Increase ~100-150 Microseconds Cause Performance Anxiety ถ้าไม่ ก็กลับไป Premature Optimization อีกครั้ง

วิธี Measure Latency นี้ จะรายละเอียดใน Part 2 เพราะ Part นี้ยาวพอแล้ว