แอปพลิเคชันซอฟต์แวร์มีค่าเท่ากับความสามารถในการตอบสนองความต้องการของลูกค้า เมื่อพิจารณาความต้องการของลูกค้า ความต้องการแรกที่เราพบคือ ความเร็วของแอปพลิเคชัน และความน่าเชื่อถือของข้อมูล อย่างไรก็ตาม เมื่อแอปพลิเคชันเติบโตและขยายไปทั่วโลก ฐานข้อมูล SQL มักจะกลายเป็นจุดคอขวดด้านประสิทธิภาพ เนื่องจากปริมาณคำขอ query เพิ่มขึ้น ความหน่วงสูงขึ้น และผู้ใช้กระจายอยู่ทั่วโลก
เพื่อแก้ไขปัญหาเหล่านี้เมื่อแอปพลิเคชันเติบโต caching เป็นหนึ่งในโซลูชันแรกที่ลดโหลดบน primary database สำหรับ repeated queries และลด latency เมื่อผู้ใช้ส่ง queries เมื่อพูดถึง cache เครื่องมือเดียวกันมักจะคิดถึงในใจเราทุกคน ใช่แล้ว นั่นคือ Redis Redis เป็นเครื่องมือที่สมบูรณ์แบบสำหรับ cache ข้อมูลเพื่อลดโหลดและทำให้แอปพลิเคชันเร็วขึ้น Upstash ยังให้ Redis replication แบบกระจายทั่วโลก ซึ่งจะทำให้แอปพลิเคชันเร็วกว่าการ cache แบบปกติอีกมาก
ในบล็อกนี้ เราจะสำรวจข้อได้เปรียบทางเทคนิคของการผสานรวม Global Redis กับฐานข้อมูล SQL อภิปรายผลกระทบต่อ latency และ scalability และให้ตัวอย่างการใช้งานจริงสำหรับการใช้ Global Redis กับ PostgreSQL และ MySQL
ประโยชน์ของ Caching
มาตรวจสอบก่อนว่าทำไมเราควรใช้ caching
มีประโยชน์หลักของ caching 2 ประการที่ผมอยากกล่าวถึงในบล็อกนี้: การลดโหลดฐานข้อมูล และการลด latency ให้กับผู้ใช้
การลดโหลดฐานข้อมูล (Reducing Database Load)
ฐานข้อมูล SQL เก่งในการจัดการ structured data และ complex queries แต่ภายใต้โหลดหนัก พวกมันอาจกลายเป็น bottleneck ปริมาณมากของ repeated queries สำหรับข้อมูลเดียวกัน - เช่น รายละเอียดสินค้า โปรไฟล์ผู้ใช้ หรือ settings ที่เข้าถ่ายบ่อย - ใช้ทรัพยากร CPU และ I/O อย่างมาก ด้วยการ cache ผลลัพธ์เหล่านี้ จำนวน queries ที่ตีเข้า database จะลดลงอย่างมาก ทำให้ database โฟกัสที่งานสำคัญกว่านี้ เช่น การประมวลผลธุรกรรมและการอัปเดต
ตัวอย่าง:
- ไม่มี caching: ฟีเจอร์ยอดนิยมบนเว็บไซต์สร้าง identical database queries หลายล้านครั้งต่อวัน ทำให้ประสิทธิภาพช้าลงสำหรับ operations อื่นๆ
- มี caching: ผลลัพธ์ query ที่เข้าถึงบ่อยถูกจัดเก็บใน high-speed cache เช่น Redis ลดอัตรา database queries ลงเกิน 90%
การลด Latency (Reducing Latency)
การลดโหลดฐานข้อมูลเป็นเพื่อสุขภาพระบบเพื่อให้แน่ใจถึงความน่าเชื่อถือของข้อมูล Caching ยังปรับปรุงเวลาที่คำขอและ queries ของผู้ใช้ใช้
เมื่อแอปพลิเคชัน query ฐานข้อมูลซ้ำๆ สำหรับข้อมูลเดียวกัน การดึงข้อมูลจะใช้เวลานานเสมอ โดยเฉพาะถ้า queries เหล่านี้สร้างโหลดมากบนฐานข้อมูล ความล่าช้าทั้งหมดนี้อาจเพิ่มขึ้นอีก นี่เป็นปัญหาเฉพาะสำหรับแอปพลิเคชันที่ต้องการ real-time data access หรือจัดการ high query volumes โดยที่ความล่าช้าเล็กน้อยก็ส่งผลต่อประสิทธิภาพอย่างมาก
Caching แก้ปัญหานี้โดยการจัดเก็บข้อมูลที่เข้าถึงบ่อยในหน่วยความจำ ซึ่งเร็วกว่าการ query ฐานข้อมูลมาก ด้วยการลดการพึ่งพา database queries สำหรับ repeated requests caching ลดการเดินทางผ่านเครือข่ายและหลีกเลี่ยง computational overhead ของการดำเนินการ complex queries ผลลัพธ์คือ response times ปรับปรุงอย่างมาก ช่วยให้แอปพลิเคชันส่งมอบประสิทธิภาพที่เร็วและสม่ำเสมอมากขึ้น แม้ภายใต้โหลดหนักหรือในสภาพแวดล้อมแบบกระจาย
กลยุทธ์ Caching ทั่วไป (Common Caching Strategies)
สำคัญที่จะเข้าใจกลยุทธ์ caching หลัก 2 แบบที่ใช้ในการเพิ่มประสิทธิภาพแอปพลิเคชัน: cache-aside และ write-through แต่ละแนวทางมี use cases และ trade-offs ขึ้นอยู่กับความต้องการของแอปพลิเคชัน
Cache-aside เป็นเทคนิค caching ที่พบบ่อยที่สุด ในเทคนิคนี้ แอปพลิเคชันตรวจสอบ cache สำหรับข้อมูลก่อน หากข้อมูลไม่อยู่ใน cache (cache miss) มันจะดึงข้อมูลจากฐานข้อมูลและเขียนลงใน cache สำหรับการใช้งานในอนาคต
นี่คือแผนภาพง่ายๆ ที่แสดงว่า cache-aside ทำงานอย่างไร ซึ่งคุณทั้งหมดอาจเคยเห็นมาก่อนมาเจอบล็อกนี้

ข้อได้เปรียบของ caching นี้คือ cache size ถูก optimize และ cache data จะถูก reload เมื่อผู้ใช้ต้องการ ข้อเสียคือข้อมูลจะไม่พร้อมใช้งานหลังจาก cache ถูกล้างเมื่อ TTL หมดไป ในขณะนั้น cache จะถูก reload เมื่อผู้ใช้ request ข้อมูลนั้น ในกรณีนี้ ผู้ใช้นั้นจะต้องรอให้ query เสร็จสิ้น แต่ไ่นั่นแน่นอน คำขอครั้งต่อไปจะสามารถดึงข้อมูลจาก cache ได้อีกครั้ง
ในกลยุทธ์ write-through ทุก write operation ไปยังฐานข้อมูลจะถูกเขียนไปยัง cache ทันทีเช่นกัน นี่รับรองว่า cache จะ up-to-date เสมอกับข้อมูลล่าสุดจากฐานข้อมูล
นี่คือแผนภาพง่ายๆ ของ write-through caching:

กลยุทธ์นี้รับรองความสอดคล้องของข้อมูลระหว่าง cache และฐานข้อมูล และไม่มี request ใดที่ประสบ higher latency เพราะข้อมูลจะพร้อมใช้งานแล้วโดยไม่ต้องรอคำขอจากผู้ใช้ อย่างไรก็ตาม ข้อเสียคือ cache จะมีข้อมูลทั้งหมด แม้จะไม่ได้ต้องการ นอกจากนี้ ทุก write operation จะได้รับ latency เนื่องจากข้อมูลจะถูกเขียนไปยัง cache ด้วย
Global Redis คืออะไร? ประโยชน์ของ Global Redis
มาเรียนรู้วิธีปรับปรุงประสิทธิภาพของ SQL database เพิ่มเติม
แหล่งที่มาอื่นของ latency คือ ตำแหน่งของฐานข้อมูล ในกรณีส่วนใหญ่ primary database ตั้งอยู่ใน regions เฉพาะ อย่างไรก็ตาม ข้อมูลควรเข้าถึงได้ในตำแหน่งที่ใกล้ที่สุด เพื่อที่เราจะลดความล่าช้าที่เกิดจากระยะทางไปยัง data store
ปัญหานี้สามารถป้องกันได้โดยการใช้ globally distributed Redis ที่ Upstash จัดเตรียมไว้
Global Redis เป็น distributed caching solution ที่ replicate ข้อมูลข้าม multiple geographical locations รับรอง low-latency access สำหรับ globally distributed applications
มาดูวิธีสร้าง global Redis อย่างรวดเร็ว ก่อนอื่น login เข้า Upstash console
หลัง login เราสามารถสร้างฐานข้อมูล Redis ได้ที่นี่ Upstash ให้ multiple locations สำหรับจัดวาง read replicas

เมื่อเลือก read locations แล้ว คุณสามารถเลือก plan และสุดท้ายสร้างฐานข้อมูล Redis ของคุณ นั่นคือทั้งหมด!
ใน console คุณสามารถ add/remove regions หลังจากสร้างฐานข้อมูลได้อีก

Global Redis databases ถูกใช้ส่วนใหญ่โดยแอปพลิเคชันที่กระจายทั่วโลก และแอปพลิเคชันที่รันที่ edge
Low latency สำหรับ globally distributed applications
ในระบบที่กระจายทั่วโลก latency มักกลายเป็น bottleneck เนื่องจากระยะทางทางกายภาพระหว่างผู้ใช้และ central database หรือ cache Global Redis แก้ปัญหานี้โดยการ replicate ข้อมูลข้าม multiple geographically distributed nodes
เมื่อผู้ใช้ request ข้อมูล closest cache node จะ serve คำขอ ลด network travel time อย่างมาก การเข้าถึงแบบ localized นี้รับรอง faster response times และ consistent user experience ไม่ว่าผู้ใช้จะอยู่ที่ไหน
เช่น ถ้าผู้ใช้อยู่ใน Tokyo แต่ database อยู่ใน Dublin ระยะทางจะทำให้ response ช้า ถ้ามี read replica ของ Upstash Redis ใน Europe คำขอก็สามารถ route ไปที่ closest read replica ซึ่งคือตัวใน Europe ในกรณีนี้
Low latency data สำหรับ edge runtimes (เช่น Cloudflare Workers)
Edge runtimes เป็น environments ที่ออกแบบมาเพื่อ execute code ที่ network's edge ใกล้ end user Edge runtimes แจกจ่าย application logic ข้าม multiple edge locations ทั่วโลก สถาปัตยกรรมนี้ลดระยะทางทางกายภาพระหว่างผู้ใช้และการ execute คำขอของพวกเขา ลด latency และปรับปรุงประสิทธิภาพอย่างมาก
ในขณะที่ edge runtimes นำ computation ใกล้ผู้ใช้ พวกมันยังต้องการการเข้าถึงข้อมูลสำหรับ operations ส่วนใหญ่ เช่น การดึงข้อมูลเฉพาะผู้ใช้ session tokens หรือ configurations โดยไม่มี caching layer ทุก request จะยังต้องการ round trip ไปยัง central database ซึ่งลดประโยชน์ของ latency มาก นี่คือที่ที่ Global Redis เล่นบทบาทสำคัญ เนื่องจากพวกมัน replicate frequently used data ไปยัง edge รับรอง low-latency access
ตัวอย่างโค้ด 1: PostgreSQL กับ Node.js
Caching ด้วย global Redis สมบูรณ์แบบ ตอนนี้เราจะดูตัวอย่างโค้ดที่ implement cache-aside strategy ด้วย Upstash Redis และ Postgresql database
เราควรติดตั้ง SDKs ที่เราจะใช้เชื่อมต่อกับ data stores ก่อน
npm install pg upstash/redis
เมื่อเรามี dependencies installed แล้ว เราสามารถเชื่อมต่อกับ data stores, Upstash Redis และ Postgres
const { Redis } = require('@upstash/redis'); // Upstash Redis SDK const { Client } = require('pg'); const redis = new Redis({ url: <UPSTASH_REDIS_REST_URL>, token: <UPSTASH_REDIS_REST_TOKEN>, }) const client = new Client({ user: 'username', password: 'password', host: 'host', port: 'port_number', database: 'database_name', }); client.connect();
ตอนนี้มาเขียนฟังก์ชันใน data access layer ของเรา ฟังก์ชันนี้สามารถปรับเปลี่ยนได้ตามความต้องการของคุณ
สมมติว่าเราต้องการแสดงข้อมูลผู้ใช้บนเว็บไซต์โดย userId ในกรณีนี้ เราควรมีฟังก์ชันที่รับ userId เป็นพารามิเตอร์
async function getUserData(userId) { // Check cache first const cachedData = await redis.get(userId); if (cachedData) { console.log('Cache hit'); return JSON.parse(cachedData); } // Fallback to database console.log('Cache miss'); const query = 'SELECT * FROM users WHERE id = $1'; const { rows } = await client.query(query, [userId]); await redis.set(userId, JSON.stringify(rows), { EX: 300 }); // Cache for 5 minutes return rows; }
นี่คือมัน! ตอนนี้ฟังก์ชันนี้จะตรวจสอบก่อนว่าข้อมูลผู้ใช้มีอยู่ใน Redis database ที่ใกล้ที่สุดกับ region ของ requester หรือไม่ หากไม่มี มันจะ query ข้อมูลที่ร้องขอจาก Postgresql database และเขียนข้อมูลที่คืนค่ากลับไปที่ Upstash Redis primary region ข้อมูลที่เขียนไปที่ primary region จะถูก copy ไปยัง read replicas ทั้งหมดโดยอัตโนมัติ
ตัวอย่างโค้ด 2: MYSQL กับ Python
ตอนนี้ มาดูตัวอย่างอีกอันคราวนี้ เราจะทำ cache implementation เดียวกัน แต่ main database จะเป็น MYSQL แทน นอกจากนี้ เราจะเขียนฟังก์ชันนี้ใน Python เพื่อดูว่ามันทำงานอย่างไรใน Python-based applications
เหมือนปกติ เราจะดาวน์โหลด dependencies ที่เราจะใช้เชื่อมต่อฐานข้อมูลก่อน
pip install upstash-redis upstash-redis
ตอนนี้ เราสามารถ initialize clients และเชื่อมต่อพวกเขาได้
import upstash_redis import mysql.connector import json # Initialize Upstash Redis client redis_client = upstash_redis.Redis( url='<your-upstash-redis-url>', token='<your-upstash-token>' ) # Initialize MySQL client db = mysql.connector.connect( host="<your-mysql-host>", user="<your-mysql-user>", password="<your-mysql-password>", database="<your-database-name>" ) cursor = db.cursor(dictionary=True)
Connections พร้อมแล้ว ตอนนี้เราจะ implement ฟังก์ชันคล้ายกันที่เรา implement ในส่วนก่อนหน้า
def get_user_data(userId): # Check the cache for the data cache_data = redis_client.get(key) if cache_data: print("Cache hit") return json.loads(cache_data) # If cache miss, query the MySQL database print("Cache miss") cursor.execute("SELECT * FROM users WHERE key = %s", (userId)) result = cursor.fetchone() if result: # Store the data in the cache with a TTL of 1 hour redis_client.set(key, json.dumps(result), ex=3600) return result
สรุป
ด้วยการผสานรวม Global Redis เข้ากับ architecture ของคุณ คุณสามารถทำให้ได้ performance gains ที่มีนัยสำคัญสำหรับ SQL-based applications โดยเฉพาะใน globally distributed environments ด้วย low-latency access, reduced database load, และความเข้ากันได้กับ edge runtimes Global Redis สามารถแก้ไขความท้าทายด้านประสิทธิภาพของแอปพลิเคชันที่มี SQL databases
ในบล็อกโพสต์นี้ เราได้ผ่านประโยชน์ของ caching ด้วย global Redis และตรวจสอบตัวอย่างบางอย่าง นี่เป็นเพียงตัวอย่างพื้นฐานที่สามารถขยายต่อได้มากขึ้นขึ้นอยู่กับความต้องการของคุณ
หวังว่าบล็อกนี้จะเป็นจุดเริ่มต้นที่ดีสำหรับคุณในการเริ่มใช้ประโยชน์จาก global Redis