Pipelines
Pipelining คืออะไร?
หัวข้อที่มีชื่อว่า “Pipelining คืออะไร?”ทุกคำสั่ง Redis มี round-trip: client ส่งคำสั่ง รอ reply แล้วจึงส่งคำสั่งถัดไป บน network ที่มี latency แม้เพียงเล็กน้อย นี่สะสมได้รวดเร็ว
Pipelining ให้ client ส่งชุดคำสั่งในการเขียนครั้งเดียวโดยไม่ต้องรอ reply ของแต่ละคำสั่ง server ประมวลผลตามลำดับและส่ง reply ทั้งหมดกลับมาพร้อมกัน ผลลัพธ์คือ round-trip เดียวแทนที่จะเป็น N round-trips
# ไม่มี pipelining: 3 round-trips127.0.0.1:6379> SET a 1OK127.0.0.1:6379> SET b 2OK127.0.0.1:6379> SET c 3OK
# มี pipelining: 1 round-trip ผลลัพธ์เหมือนกันRedis client library ส่วนใหญ่เปิด pipelining โดยตรง ตัวอย่างใน Node.js (ioredis):
const pipeline = redis.pipeline();pipeline.set('a', 1);pipeline.set('b', 2);pipeline.set('c', 3);const results = await pipeline.exec();redis-cli —pipe mode
หัวข้อที่มีชื่อว่า “redis-cli —pipe mode”redis-cli มาพร้อม flag --pipe ที่รับ Redis protocol (RESP) จาก stdin และส่งเป็น pipeline:
# สร้าง RESP inline และส่งผ่าน pipe ไปยัง Redisprintf "*3\r\n\$3\r\nSET\r\n\$2\r\nk1\r\n\$5\r\nhello\r\n*3\r\n\$3\r\nSET\r\n\$2\r\nk2\r\n\$5\r\nworld\r\n" \ | redis-cli --pipeเหมาะสำหรับ bulk import: เครื่องมืออย่าง redis-cli --pipe สามารถโหลดได้นับล้าน key ในเวลาไม่กี่วินาทีโดยส่ง batch ขนาดใหญ่ผ่าน connection เดียว
คุณยังสามารถสร้างไฟล์คำสั่งและส่งผ่าน pipe:
# commands.txt มีคำสั่ง redis-cli หนึ่งบรรทัดต่อหนึ่งคำสั่งcat commands.txt | redis-cli --pipePipelines vs transactions
หัวข้อที่มีชื่อว่า “Pipelines vs transactions”Pipeline และ transaction มักถูกสับสน ตารางด้านล่างชี้แจงความแตกต่าง:
| คุณสมบัติ | Pipeline | Transaction (MULTI/EXEC) |
|---|---|---|
| Round-trips | หนึ่ง (หรือน้อย) | หนึ่งต่อคำสั่ง + EXEC |
| Atomicity | ไม่มี — client อื่นสามารถแทรกได้ | ใช่ — ไม่มีการขัดจังหวะ |
| Rollback | ไม่มี | ไม่มี |
| Use case | Throughput / bulk load | การเขียนกลุ่มที่ปลอดภัย |
Pipeline คือ network optimization Transaction คือ atomicity guarantee คุณสามารถรวมทั้งสองได้: client library หลายตัวให้คุณส่งบล็อก MULTI/EXEC ภายใน pipeline เพื่อได้ประโยชน์ทั้งคู่
SET a 1
SET b 2
SET c 3
MGET a b cข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
| Pipeline (batch หลายคำสั่งใน request เดียว) | ลด network round-trip เหลือแทบ 1 ครั้ง เพิ่ม throughput ได้มากสำหรับ bulk operation | ไม่มี atomicity — client อื่นสามารถแทรกคำสั่งระหว่างคำสั่งใน pipeline ได้ |
redis-cli --pipe สำหรับ bulk import | โหลดข้อมูลจำนวนล้าน key ได้ในไม่กี่วินาที ผ่าน connection เดียว | ต้องสร้าง RESP protocol เองหรือใช้ command file ดีบักยากกว่าคำสั่งทีละบรรทัด |
รวม MULTI/EXEC ไว้ใน pipeline | ได้ทั้ง round-trip น้อยและ atomicity guarantee | เพิ่มความซับซ้อนของโค้ด client ต้องเข้าใจทั้งสองแนวคิดควบคู่กัน |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- คิดว่า pipeline ให้ atomicity เหมือน transaction — pipeline เป็นแค่ network optimization ที่รวมคำสั่งไปในการเขียนครั้งเดียว client อื่นยังสามารถรันคำสั่งของตัวเองแทรกระหว่างคำสั่งใน pipeline ได้ ถ้าต้องการ atomicity ต้องห่อด้วย
MULTI/EXEC - ส่ง pipeline ขนาดใหญ่เกินไปในครั้งเดียว — batch ที่ใหญ่มากอาจทำให้ memory buffer ทั้งฝั่ง client และ server พองขึ้นชั่วคราว ควรแบ่งเป็น batch ขนาดพอเหมาะ (เช่น หลักพันคำสั่งต่อ pipeline)
- ไม่ตรวจสอบผลลัพธ์แต่ละคำสั่งใน pipeline — pipeline คืน array ของผลลัพธ์ตามลำดับคำสั่ง หากมีคำสั่งใดผิดพลาดระหว่างทาง คำสั่งอื่นยังรันต่อ ต้อง loop ตรวจ error ในผลลัพธ์เอง ไม่ใช่ assume ว่าทั้ง batch สำเร็จหมด
💡 ตัวอย่างจากของจริง
Bulk data import job ทั่วไป — ใช้
redis-cli --pipeหรือ client library pipelining เพื่อโหลดข้อมูล seed หรือ migrate ข้อมูลนับล้าน key เข้า Redis โดยลด round-trip จากนับล้านครั้งเหลือเพียงไม่กี่ batchAnalytics/logging pipeline — ระบบที่ต้องเขียน event จำนวนมากต่อวินาทีมักรวมคำสั่ง
SET/INCR/ZADDเป็น pipeline เพื่อให้ throughput สูงพอสำหรับ traffic ที่มี volume สูง