ลดความยุ่งยากในการใช้คลาวด์ พูดคุยกับเจ้าหน้าที่

Home ติดตั้งและตั้งค่า Redis บน Linux Server

ติดตั้งและตั้งค่า Redis บน Linux Server

Redis เป็นฐานข้อมูลแบบ Key-Value ที่เก็บข้อมูลไว้ในหน่วยความจำ จึงอ่านเขียนได้เร็วมาก นิยมใช้เป็น Cache ของเว็บไซต์ (เช่น Object Cache ของ WordPress), เก็บ Session ของผู้ใช้, ทำคิวงาน (Queue) ของ Laravel หรือเก็บตัวนับต่าง ๆ การใช้ Redis ช่วยลดจำนวน Query ที่ต้องวิ่งไปยัง MySQL ได้มาก

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

สิ่งที่ต้องเตรียม

  • Ubuntu 22.04/24.04 หรือ AlmaLinux/Rocky Linux 8-9 และผู้ใช้ที่มีสิทธิ์ sudo
  • RAM ว่างพอสำหรับข้อมูลที่จะเก็บใน Redis (ตรวจด้วย free -h ดู ตรวจสอบ CPU, RAM และ Load Average ของ Linux Server)
  • แอปพลิเคชันที่จะใช้ Redis รันอยู่บนเครื่องเดียวกัน (กรณีต่างเครื่อง ดูหัวข้อท้ายบทความ)

ความแตกต่างระหว่าง Distro ที่ต้องรู้ก่อน:

UbuntuAlmaLinux / Rocky 9AlmaLinux / Rocky 8
ชื่อแพ็กเกจredis-serverredisredis
ชื่อ Serviceredis-serverredisredis
ไฟล์ตั้งค่า/etc/redis/redis.conf/etc/redis/redis.conf/etc/redis.conf
ไฟล์ Log/var/log/redis/redis-server.log/var/log/redis/redis.log/var/log/redis/redis.log

เวอร์ชันของ Redis ขึ้นกับ Repository ของแต่ละ Distro (Ubuntu 22.04 ได้ 6.0, 24.04 ได้ 7.0) คำสั่งในบทความนี้ใช้ได้กับ Redis 6 ขึ้นไป

ขั้นตอนที่ 1: ติดตั้ง Redis

# Ubuntu
sudo apt update
sudo apt install -y redis-server

# AlmaLinux / Rocky Linux
sudo dnf install -y redis
sudo systemctl enable --now redis

บน AlmaLinux/Rocky 8 Module Stream เริ่มต้นคือ Redis 5 ซึ่งยังไม่มีระบบ ACL ให้เปิด Stream 6 ก่อนติดตั้ง:

sudo dnf module enable -y redis:6
sudo dnf install -y redis

บน Ubuntu Service จะเริ่มทำงานและตั้งให้เริ่มเมื่อบูตให้อัตโนมัติ ตรวจเบื้องต้นด้วย:

redis-cli ping

ต้องได้คำตอบ PONG

ขั้นตอนที่ 2: สำรองไฟล์ตั้งค่าและตรวจการ Bind

sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.orig

(บน AlmaLinux/Rocky 8 ให้ใช้ Path /etc/redis.conf แทนทุกจุดในบทความนี้)

เปิดไฟล์แล้วตรวจค่าต่อไปนี้:

sudo nano /etc/redis/redis.conf
bind 127.0.0.1 -::1
protected-mode yes
port 6379
  • bind 127.0.0.1 -::1 รับเฉพาะการเชื่อมต่อจากเครื่องตัวเองทั้ง IPv4 และ IPv6 เครื่องหมาย - หน้า ::1 หมายถึงถ้าเครื่องไม่มี IPv6 ก็ไม่ต้องแจ้ง Error รูปแบบนี้ใช้ได้เฉพาะ Redis รุ่นใหม่ ถ้าไฟล์ของแพ็กเกจที่คุณได้มาเขียนไว้เป็น bind 127.0.0.1 ::1 (เช่น Redis 6.0 บน Ubuntu 22.04) ให้คงบรรทัดเดิมไว้ ทั้งสองแบบให้ผลเหมือนกันเมื่อเครื่องมี IPv6
  • protected-mode yes เป็นชั้นป้องกันเพิ่มเติม ถ้าไม่มีรหัสผ่านและไม่ได้ Bind ไว้ Redis จะปฏิเสธการเชื่อมต่อจากภายนอก

ห้ามเปลี่ยน bind เป็น 0.0.0.0 เพื่อให้แอปเชื่อมต่อได้ ถ้าแอปอยู่บนเครื่องเดียวกัน 127.0.0.1 ก็เพียงพอ

ขั้นตอนที่ 3: ตั้งรหัสผ่านด้วย ACL

ตั้งแต่ Redis 6 มีระบบ ACL ที่แยกผู้ใช้และสิทธิ์ได้ วิธีที่ง่ายที่สุดคือตั้งรหัสผ่านให้ผู้ใช้ default ผ่านค่า requirepass ซึ่งใช้ได้ทุกเวอร์ชัน สร้างรหัสผ่านยาวแบบสุ่มก่อน:

openssl rand -base64 32 | tr -d '/+=' | cut -c1-40

แล้วใส่ในไฟล์ตั้งค่า:

requirepass ใส่รหัสผ่านที่สร้างไว้

ไฟล์ตั้งค่าเก็บรหัสผ่านเป็นข้อความธรรมดา ตรวจให้แน่ใจว่าผู้ใช้อื่นอ่านไม่ได้:

ls -l /etc/redis/redis.conf

ผู้ใช้อื่น (ตัวอักษรชุดสุดท้ายของสิทธิ์) ต้องไม่มีสิทธิ์อ่าน หากมี ให้ปรับด้วย sudo chmod 640 /etc/redis/redis.conf โดยคงเจ้าของและกลุ่มเดิมของแพ็กเกจไว้ เพื่อให้ Service ยังอ่านไฟล์ได้

หากต้องการแยกผู้ใช้ให้แต่ละแอป เช่น ให้เว็บใช้ได้เฉพาะ Key ที่ขึ้นต้นด้วย site1: และห้ามคำสั่งอันตราย ให้เพิ่มบรรทัด ACL ในไฟล์เดียวกัน:

user site1 on >รหัสผ่านของsite1 ~site1:* +@all -@dangerous

-@dangerous ตัดคำสั่งกลุ่มอันตราย เช่น FLUSHALL, CONFIG, DEBUG ออกจากผู้ใช้นี้ กลุ่มนี้รวมคำสั่ง KEYS ด้วย ก่อนใช้จริงให้ตรวจว่าแอปหรือปลั๊กอินของคุณไม่ได้เรียกคำสั่งในกลุ่มนี้

ขั้นตอนที่ 4: จำกัดหน่วยความจำและเลือกนโยบายเมื่อเต็ม

ถ้าไม่จำกัด Redis จะใช้ RAM เพิ่มไปเรื่อย ๆ จนระบบต้องฆ่าโปรเซส (OOM Killer) ซึ่งอาจไปฆ่า MySQL แทน ให้กำหนด:

maxmemory 256mb
maxmemory-policy allkeys-lru
นโยบายเหมาะกับ
allkeys-lruใช้ Redis เป็น Cache ล้วน ลบ Key ที่ไม่ได้ใช้นานที่สุดเมื่อเต็ม
volatile-lruมีทั้ง Cache (มีวันหมดอายุ) และข้อมูลถาวรปนกัน ลบเฉพาะ Key ที่ตั้งเวลาหมดอายุไว้
noevictionใช้เป็นคิวงานหรือ Session ที่ห้ามหาย เมื่อเต็มจะปฏิเสธการเขียนแทนการลบ

ตัวเลข 256mb เป็นเพียงตัวอย่าง สำหรับเครื่องที่มี RAM 2 GB และรันเว็บกับฐานข้อมูลไปด้วย 128-256 MB มักเพียงพอสำหรับ Object Cache ของเว็บขนาดเล็ก

ขั้นตอนที่ 5: ตั้งค่าการบันทึกลงดิสก์

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

save ""

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

ขั้นตอนที่ 6: รีสตาร์ตและปรับค่า Kernel

# Ubuntu
sudo systemctl restart redis-server

# AlmaLinux / Rocky Linux
sudo systemctl restart redis

Redis มักแจ้งเตือนใน Log ว่า WARNING Memory overcommit must be enabled! เพราะการบันทึก RDB ใช้การ fork โปรเซส ซึ่งอาจล้มเหลวเมื่อ RAM ใกล้เต็ม แก้โดย:

echo 'vm.overcommit_memory = 1' | sudo tee /etc/sysctl.d/99-redis.conf
sudo sysctl --system

ตรวจสอบผลลัพธ์

เข้า redis-cli แล้วยืนยันตัวตนภายในโปรแกรม เพื่อไม่ให้รหัสผ่านไปอยู่ใน History ของ Shell:

redis-cli
127.0.0.1:6379> AUTH ใส่รหัสผ่าน
OK
127.0.0.1:6379> PING
PONG
127.0.0.1:6379> CONFIG GET maxmemory*
127.0.0.1:6379> INFO memory

ถ้าเรียก PING โดยยังไม่ AUTH ต้องได้ NOAUTH Authentication required. ซึ่งยืนยันว่ารหัสผ่านทำงาน สำหรับผู้ใช้ ACL ให้ใช้ AUTH site1 รหัสผ่าน และตรวจการ Bind ด้วย:

sudo ss -tlnp | grep 6379

ต้องเห็นเฉพาะ 127.0.0.1:6379 และ [::1]:6379 ไม่มี 0.0.0.0 หรือ * (ดูวิธีอ่านผลได้ที่ ตรวจสอบพอร์ตที่เปิดอยู่บน Linux ด้วย ss และ lsof)

ในแอปพลิเคชัน ให้ตั้งค่า Host เป็น 127.0.0.1 พอร์ต 6379 และรหัสผ่านที่ตั้งไว้ เช่น Laravel ใช้ REDIS_HOST, REDIS_PASSWORD ในไฟล์ .env ส่วน WordPress ต้องใช้ปลั๊กอิน Object Cache ร่วมกับส่วนขยาย PHP สำหรับ Redis (บน Ubuntu คือแพ็กเกจ php-redis หรือ php8.x-redis ส่วนบน AlmaLinux/Rocky ชื่อแพ็กเกจขึ้นกับ Repository ที่ใช้ติดตั้ง PHP)

หากแอปอยู่คนละเครื่องกับ Redis

อย่าเปิดพอร์ต 6379 ออกอินเทอร์เน็ต ทางเลือกที่ปลอดภัยคือ เชื่อมสองเครื่องผ่าน VPN ภายใน เช่น ติดตั้ง VPN ด้วย WireGuard บน Linux Server แล้วเพิ่ม IP ของ VPN ในบรรทัด bind (เช่น bind 127.0.0.1 -::1 10.8.0.1) และเปิด Firewall ให้เฉพาะ IP ของเครื่องแอปเท่านั้น หากเซิร์ฟเวอร์มี Security Group หรือ Firewall ภายนอกจากฝั่งผู้ให้บริการ ให้ตรวจว่าไม่ได้เปิดพอร์ตนี้ให้ทุก IP

ปัญหาที่พบบ่อย

Redis เริ่มไม่ได้หลังแก้ไฟล์ตั้งค่า

มักเกิดจากพิมพ์ค่าผิดรูปแบบ เช่น maxmemory 256 mb (มีเว้นวรรค) ดูข้อความ Error ด้วย sudo journalctl -u redis-server -n 30 (หรือ -u redis) บรรทัดที่ผิดจะแสดงพร้อมเลขบรรทัด

แอปแจ้ง NOAUTH หรือ WRONGPASS

แอปยังไม่ได้ส่งรหัสผ่าน หรือรหัสผ่านมีอักขระพิเศษที่ต้อง Escape ในไฟล์ตั้งค่าของแอป ควรสร้างรหัสผ่านที่มีเฉพาะตัวอักษรและตัวเลขตามคำสั่งในขั้นตอนที่ 3

OOM command not allowed when used memory > maxmemory

ข้อมูลเต็มตาม maxmemory และนโยบายเป็น noeviction ให้เพิ่ม maxmemory หรือเปลี่ยนนโยบายเป็น allkeys-lru ถ้าข้อมูลทั้งหมดเป็น Cache

Could not connect to Redis at 127.0.0.1:6379: Connection refused

Service ไม่ทำงาน หรือเปลี่ยน port ไปแล้ว ตรวจด้วย systemctl status redis-server (Ubuntu) หรือ systemctl status redis (AlmaLinux/Rocky)

หากต้องการคำแนะนำเรื่องขนาดหน่วยความจำหรือการใช้ Redis กับแอปของคุณ ติดต่อทีมซัพพอร์ต THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/

ผู้ให้บริการคลาวด์ไทย
เพื่อธุรกิจของคนไทย

"มุ่งมั่น" และ "มั่นคง"
พร้อมรับมือทุกการเติบโต
Trust Cloud
คลาว์ที่ปลอดภัย
คือรากฐานที่มั่นคง
cloud security