EQVPS

วิธีติดตั้ง Redis บน VPS: จำกัดหน่วยความจำ บันทึกลงดิสก์ และรหัสผ่านที่ไม่หลุด

ติดตั้ง Redis บน Ubuntu 24.04 จำกัดหน่วยความจำไม่ให้กินทั้งเซิร์ฟเวอร์ เปิดไฟล์ AOF โดยไม่ลบข้อมูล และตั้งรหัสผ่านที่ยังอยู่หลังรีสตาร์ต สองขั้นตอนในนี้มีกับดักที่เราเองเคยพลาดบนเซิร์ฟเวอร์ทดสอบ

Redis เก็บข้อมูลในหน่วยความจำและตอบสนองภายในราวหนึ่งมิลลิวินาที จึงอยู่เบื้องหลังแอปจำนวนมากในฐานะแคช คิว หรือที่เก็บเซสชัน การติดตั้งใช้คำสั่งเดียว งานจริงอยู่ที่ค่าเริ่มต้น ได้แก่ ไม่มีการจำกัดหน่วยความจำ สแนปช็อตอาจทำให้การเขียนล่าสุดหาย และมีความผิดพลาดง่าย ๆ สองข้อที่ลบข้อมูลหรือปิดรหัสผ่านไปแบบเงียบ ๆ คู่มือนี้ครอบคลุมทั้งหมดบน Ubuntu 24.04 เราทดลองทุกขั้นตอนบนอิมเมจของเรา ตัวเลขมาจากเซิร์ฟเวอร์ Micro (2 vCPU, 2 GB)

คุณต้องมีผู้ใช้ที่ใช้ sudo ได้ คู่มือตั้งค่า Ubuntu จะสร้างให้

1. ติดตั้ง

sudo apt update
sudo apt install -y redis-server
redis-server --version
redis-cli ping

การติดตั้งใช้เวลา 13 วินาที ได้ Redis 7.0.15 มันเริ่มทำงานทันทีและทุกครั้งที่บูต ตอบ PONG และรับการเชื่อมต่อ เฉพาะบนตัวเซิร์ฟเวอร์เอง คือ 127.0.0.1:6379 และ [::1]:6379 พร้อม protected-mode yes ขณะไม่มีข้อมูลใช้ RAM 13.5 MB

ในล็อกมีคำเตือนอยู่แล้ว:

WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition.

Redis บันทึกลงดิสก์จากสำเนาของตัวเองที่สร้างด้วย fork และด้วยค่าเริ่มต้นของเคอร์เนล fork นี้อาจล้มเหลวเมื่อหน่วยความจำตึง แก้ครั้งเดียวพอ:

echo 'vm.overcommit_memory = 1' | sudo tee /etc/sysctl.d/90-redis.conf
sudo sysctl -p /etc/sysctl.d/90-redis.conf
sudo systemctl restart redis-server

หลังรีสตาร์ต คำเตือนหายไป

2. จำกัดหน่วยความจำ

ค่าเริ่มต้นของ maxmemory คือ 0 หมายถึงไม่จำกัด และนโยบายคือ noeviction Redis จะใช้ RAM ไปเรื่อย ๆ จนเซิร์ฟเวอร์หมด ตั้งเพดานไว้และตัดสินใจว่าเมื่อถึงเพดานแล้วจะเกิดอะไรขึ้น:

redis-cli CONFIG SET maxmemory 256mb
redis-cli CONFIG SET maxmemory-policy allkeys-lru
redis-cli CONFIG REWRITE

เราทดสอบทั้งสองนโยบายด้วยเพดาน 64 MB และการเขียน 400,000 ครั้ง:

  • noeviction (ค่าเริ่มต้น): หน่วยความจำหยุดที่ 63 MB และการเขียนใหม่ล้มเหลวด้วย OOM command not allowed when used memory > 'maxmemory' เหมาะกับคิวหรือข้อมูลที่เสียไม่ได้
  • allkeys-lru: Redis ทิ้งคีย์ที่ไม่ได้ใช้นานที่สุด รวม 48,606 คีย์ และการเขียนผ่านทั้งหมด เหมาะกับแคช

CONFIG REWRITE บันทึกค่าที่ใช้อยู่ลงใน /etc/redis/redis.conf ให้คงอยู่หลังรีสตาร์ต และยังเพิ่มบรรทัดหนึ่งที่คุณต้องรู้ก่อนขั้นตอนที่ 4

3. เลือกวิธีบันทึกลงดิสก์

โดยค่าเริ่มต้น Redis เขียนสแนปช็อต (/var/lib/redis/dump.rdb) หลังมีการเปลี่ยนแปลง 1 ครั้งในหนึ่งชั่วโมง 100 ครั้งในห้านาที หรือ 10,000 ครั้งในหนึ่งนาที เราทดสอบการหยุดสามแบบ:

Redis หยุดอย่างไรเฉพาะสแนปช็อต (ค่าเริ่มต้น)มีไฟล์ AOF
systemctl restartไม่มีอะไรหาย: บันทึกตอนปิดไม่มีอะไรหาย
ถูกฆ่าด้วย kill -9คีย์ที่เขียนหลังสแนปช็อตล่าสุดหายไปคีย์ที่เขียน 2 วินาทีก่อนยังอยู่

ทั้งสองกรณี systemd เปิด Redis ขึ้นมาใหม่เองภายในไม่กี่วินาที

ถ้า Redis เก็บข้อมูลที่หายไปแล้วคุณจะเสียดาย ให้เปิดไฟล์ AOF (append-only file) มันบันทึกทุกการเขียนและส่งลงดิสก์วินาทีละครั้ง ให้ทำบนเซิร์ฟเวอร์ที่กำลังทำงาน ไม่ใช่ด้วยการแก้ไฟล์:

redis-cli CONFIG SET appendonly yes
redis-cli CONFIG REWRITE
redis-cli INFO persistence | grep aof_

เราลองอีกวิธีก่อน และมันทำให้ข้อมูลหาย เราเปลี่ยน appendonly no เป็น appendonly yes ใน redis.conf แล้วรีสตาร์ต Redis เปิดขึ้นมาพร้อม AOF ว่างเปล่าและไม่โหลดอะไรจากสแนปช็อต คีย์เดิมทั้งหมดจึงหายไป จากนั้นตอนปิดครั้งถัดไป มันยังเขียนเนื้อหาใหม่ที่ไม่มีคีย์เก่าทับ dump.rdb อีกด้วย CONFIG SET ป้องกันเรื่องนี้ได้ เพราะ Redis จะเขียน AOF จากข้อมูลในหน่วยความจำก่อน หลังรีสตาร์ต คีย์ของเราอยู่ครบ

ถ้า Redis เป็นแค่แคชที่เริ่มว่างได้ ให้ทำตรงกันข้ามและปิดการบันทึกด้วย redis-cli CONFIG SET save ""

4. ตั้งรหัสผ่าน

นี่คือกับดักที่สอง หลังจาก CONFIG REWRITE ครั้งใดก็ตาม Redis 7 จะเพิ่มบรรทัดนี้ไว้ท้าย redis.conf:

user default on nopass ~* &* +@all

แปลว่า "ผู้ใช้เริ่มต้นไม่ต้องใช้รหัสผ่าน" จากนั้นเราเพิ่ม requirepass ไว้ด้านบนในไฟล์แล้วรีสตาร์ต Redis ยังตอบ PONG โดยไม่ต้องใช้รหัสผ่าน เพราะบรรทัด user มีผลเหนือกว่า ให้ตั้งรหัสผ่านผ่าน Redis แทน:

REDIS_PASS=$(openssl rand -hex 24)
echo "$REDIS_PASS"
redis-cli CONFIG SET requirepass "$REDIS_PASS"
REDISCLI_AUTH="$REDIS_PASS" redis-cli CONFIG REWRITE

เก็บรหัสผ่านไว้ในที่ปลอดภัย ตอนนี้ Redis เก็บมันเป็นแฮช SHA-256 ในบรรทัด user default เดียวกัน หลังรีสตาร์ต redis-cli ping ตอบ NOAUTH Authentication required. และใช้ได้เฉพาะเมื่อใส่รหัสผ่าน ส่งรหัสผ่านให้ redis-cli ผ่านตัวแปร REDISCLI_AUTH ถ้าใช้ -a รหัสผ่านจะปรากฏในรายการโปรเซส และ redis-cli จะเตือน ในแอปให้ใส่ไว้ในที่อยู่ Redis: redis://:PASSWORD@127.0.0.1:6379/0

5. เข้าถึงจากคอมพิวเตอร์ของคุณ

ให้ Redis อยู่ที่ 127.0.0.1 ต่อไป แล้วใช้อุโมงค์ SSH ระบุพอร์ต SSH ของเซิร์ฟเวอร์ ซึ่งในแพ็กเกจ NAT คือพอร์ตส่วนตัวของคุณ:

ssh -N -L 6380:127.0.0.1:6379 deploy@YOUR_SERVER_IP -p 22

ระหว่างที่อุโมงค์เปิดอยู่ redis-cli -p 6380 และเครื่องมือบนคอมพิวเตอร์ของคุณจะคุยกับ Redis บนเซิร์ฟเวอร์ โดยไม่มีอะไรใหม่เปิดสู่อินเทอร์เน็ต ด้วย คู่มือคีย์ SSH อุโมงค์จะล็อกอินได้โดยไม่ต้องใช้รหัสผ่าน

เร็วแค่ไหน

บนเซิร์ฟเวอร์ทดสอบ Micro redis-benchmark กับไคลเอนต์ 50 ตัวให้ผลดังนี้:

การทดสอบคำขอต่อวินาทีความหน่วงค่ามัธยฐาน
SET30,3031.0 ms
GET35,1490.9 ms
SET, 16 คำสั่งต่อหนึ่งรอบไปกลับ272,1092.4 ms
GET, 16 คำสั่งต่อหนึ่งรอบไปกลับ414,9381.3 ms

สำหรับแคชหรือคิวงานของเว็บแอป นี่มากเกินกว่าที่คุณจะต้องใช้ ความเร็วที่เพิ่มขึ้นมาจากการส่งคำสั่งเป็นชุด (pipelining)

เลือกแพ็กเกจไหน

Redis ต้องการ RAM สำหรับข้อมูลของคุณและแทบไม่ต้องการอะไรอื่น Nano (2 vCPU, 1 GB, $3/เดือน) รัน Redis คู่กับแอปเล็ก ๆ ได้ด้วย maxmemory 256mb ส่วน Micro (2 GB, $5/เดือน) เหลือพื้นที่สำหรับแคชที่ใหญ่ขึ้นและตัวแอป ถ้ามีเครื่องอื่นต้องเชื่อมต่อ Redis โดยตรง ให้ใช้ IPv4 ของคุณเอง (เริ่มที่ Nano-IP $8/เดือน) และอนุญาตเฉพาะที่อยู่นั้นใน ไฟร์วอลล์ แพ็กเกจทั้งหมดอยู่ในหน้า VPS ชำระเงินด้วย USDT, USDC หรือ ETH บนเครือข่าย Base, Ethereum หรือ Polygon

คำถามที่พบบ่อย

Redis ต้องใช้ RAM เท่าไร?

ตัว Redis เองเล็กมาก บนเซิร์ฟเวอร์ของเราใช้ 13.5 MB ทันทีหลังติดตั้ง สิ่งที่ต้องการคือพื้นที่สำหรับข้อมูลของคุณ เพราะข้อมูลอยู่ในหน่วยความจำ ตั้ง maxmemory ตามที่เซิร์ฟเวอร์แบ่งให้ได้ เช่น 256 MB บนเซิร์ฟเวอร์ 1 GB แล้วเลือกว่าเมื่อเต็มจะให้ทำอะไร

Redis หรือ Valkey?

Valkey คือ fork ของ Redis ที่แยกออกมาจาก Redis 7.2 และใช้โปรโตคอลเดียวกัน ไคลเอนต์ส่วนใหญ่จึงใช้ได้กับทั้งสองตัว Ubuntu 24.04 มีแค่ Redis 7.0.15 ส่วน Debian 13 มีทั้ง Redis 8.0 และ Valkey 8.1 และ Debian 12 ได้ Valkey 8.0 จาก backports ขั้นตอนในคู่มือนี้ใช้ได้กับทั้งสองตัว

ทำไม Redis ถึงเสียข้อมูลหลังระบบล่ม?

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

เพิ่ม requirepass ใน redis.conf แล้ว ทำไม Redis ยังรับคำสั่งโดยไม่มีรหัสผ่าน?

น่าจะเป็นเพราะเคยมีการรัน CONFIG REWRITE ใน Redis 7 คำสั่งนี้จะเพิ่มบรรทัด user default on nopass ~* &* +@all ไว้ท้าย redis.conf และบรรทัดนี้ทำให้ requirepass ที่เขียนไว้ด้านบนไม่มีผล ให้ตั้งรหัสผ่านด้วย CONFIG SET requirepass แล้วรัน CONFIG REWRITE จากนั้น Redis จะเก็บรหัสผ่านไว้ในบรรทัดนั้นเอง

เปิดพอร์ต 6379 สู่อินเทอร์เน็ตได้ไหม?

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

ความคิดเห็น

ยังไม่มีความคิดเห็น เป็นคนแรกสิ

แสดงความคิดเห็น

ความคิดเห็นจะถูกตรวจสอบก่อนแสดง