ฝาก Session ไว้ที่ Redis เพื่อให้ง่ายต่อการ Scale Web Application

ฝาก Session ไว้ที่ Redis เพื่อให้ง่ายต่อการ Scale Web Application

เกริ่นนำกันก่อนนะครับ หลายๆคนที่เริ่มทำ Web Scale พวก Load Balancer , HA ต่างๆ ปัญหาแรกๆที่เจอเลยก็น่าจะเป็นเรื่องของ Session หลุดเพราะลืมนึกถึง Application ที่มีการใช้งาน Session โดย default แล้ว session ก็จะเกาะอยู่ใน Web Server ของใครของมัน พอเวลา Load Balancer ทำการกระจายโหลดไปยัง Web Server เครื่องอื่นๆก็จะทำให้ session หลุด วิธีแก้ที่ผมพบเจอก็มีอยู่ 2 ทางคือ

1 )  ทำ Load Balance ในโหมด Sticky หรือพูดง่ายๆคือหากมี Client เชื่อมมาแล้ว server load balance เลือกให้เลยว่าคนนี้เข้าเครื่องไหน ก็จะเข้า web server เครื่องเดิมตลอดทำให้ session ไม่หลุด แต่ในความเห็นส่วนตัวของผมนั้นมองว่าไม่ค่อยเวิร์ค เพราะ Load Balance จะต้องเพิ่มกระบวนการเช็คในส่วนนี้ทำให้มี Overhead ต่างๆเข้ามาอีก

2) แชร์ session ไว้ที่เดียวและให้ Web Server เข้ามาอ่าน Session ที่เดียวกันวิธีนี้ผมจะมานำเสนอในบทความนี้ครับ ซึ่งช่วงแรกๆผมเคยทำการ Share ผ่าน NFS และ mount path Session มาใช้งาน ปัญหาก็คือไฟล์ session ถูกเก็บบน Disk และไหนจะมีเรื่องของ Overhead ของ NFS อีกมันก็เลยช้าครับ เลยเปลี่ยนมาเป็น Redis ซึ่งเป็น key value Storage ข้อมูลจะถูก Store ไว้บนแรมทำให้เร็วกว่า NFS หลายเท่า ผมเลยเปลี่ยนมาเป็น Redis จนถึงปัจุบันก็ยังใช้ redis เก็บ session เป็นหลักครับ

เครื่อสำหรับการทดลอง

ขอข้ามกระบวนการติดตั้ง Web Server ไปเลยนะครับ หรือใครยังไม่เคยติดตั้งสามารถย้อยอ่านบทความเก่าๆได้ ที่นี่

การติดตั้ง Redis Server (SV2)

yum -y install epel-release
yum -y update
yum -y install redis

Screen Shot 2558-12-14 at 6.20.06 PM

ตั้ง Password เพื่อความปลอดภัยโดยค้นหา  requirepass ปกติถ้าติดตั้งผ่าน Package Install ไฟล์ config จะอยู่ที่ /etc/redis.conf และตั้ง Password ได้เลยครับ ในที่นี้ผมตั้ง Password ว่า Putter และตั้งค่า Bind เพื่อให้รอ connect จากเครื่องอื่นๆ ในที่นี้ผมใส่ 0.0.0.0 ไว้เพื่อทดสอบเท่านั้น หากใช้งานใน Production จริงควร Allow เฉพาะ IP Addess ของเครื่องที่จะมา connect เท่านั้น

screen1 

Screen Shot 2558-12-14 at 6.40.42 PM

หลังจากนั้น start service และทดสอบ access เข้า redis server

redis-cli -h 172.16.209.137
redis 172.16.209.137:6379> keys *
(error) ERR operation not permitted
redis 172.16.209.137:6379> AUTH Putter
OK
redis 172.16.209.137:6379> keys *
(empty list or set)
redis 172.16.209.137:6379> 

จากการทดสอบจะเห็นว่าสามารถ Access เข้าเซิฟเวอร์ของ redis ได้และผมได้ AUTH ด้วย password ที่ผมตั้งไว้หลังจากนั้นลองโชว์ข้อมูลด้วยคำสั่ง keys * เสร็จสิ้นการติดตั้ง Redis Server สำหรับเก็บ Session


ตั้งค่า php.ini เพื่อเก็บ Session ไว้ที่ Redis
(SV1)

ติดตั้ง redis extension

pecl install redis

และนำ extension=redis.so ไปใส่ไว้ใน php.ini ด้วย หลังจากนั้นทดสอบเข้า phpinfo เพื่อเช็ค extension

Screen Shot 2558-12-14 at 7.05.27 PM

โดยปกติ php จะเก็บ session ไว้ที่ /var/lib/php/session

Screen Shot 2558-12-14 at 6.53.17 PM

ต่อไปเป็นการเปลี่ยนการเก็บ Session ให้ไปฝากไว้ที่ Redis ครับ แก้ไฟล์ php.ini ตามนี้

session.save_handler = redis
session.save_path = "tcp://172.16.209.137:6379?auth=Putter"

เสร็จแล้วให้ restart web server ครับ ทดสอบใช้งาน session

Screen Shot 2558-12-14 at 7.50.38 PM

ถ้าไม่มีอะไรผิดพลาด Session จะถูกนำมาเก็บไว้ที่ Redis Server

Screen Shot 2558-12-14 at 7.52.07 PM

 

หากนำไปใช้งานใน Production ควรวาง Redis Server ไว้เป็น Private Zone และ Allow เฉพาะ IP Web Server ที่จะ access เท่านั้นนะครับ และต้องเพิ่มในส่วนของการทำ fail over ป้องกัน redis เสียหายครับ ไว้บทความหน้าจะมาเขียนรายละเอียดการทำ Redis Cluster ต่อให้อีกทีครับ