Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

ซิงโครไนซ์สถานะ Redis กับฐานข้อมูลของคุณอย่างราบรื่นโดยใช้ QStash

ในบทความก่อนหน้านี้ เราได้พูดคุยถึงวิธีที่เราสามารถใช้ Redis เพื่อจัดเก็บสถานะโควต้าผู้ใช้ของคุณบนแอป Next.js แบบเต็มสแต็ก การทำเช่นนี้ช่วยให้เราสามารถปรับปรุงประสิทธิภาพของแอปพลิเคชันของเราได้ เนื่องจากโดยทั่วไปแล้ว Redis จะเร็วกว่าฐานข้อมูลมาก

Upstash Redis เป็นตัวเลือกที่ยอดเยี่ยมเป็นพิเศษสำหรับกรณีการใช้งานนี้ เนื่องจากเป็นฐานข้อมูล Redis ที่มีการจัดการเต็มรูปแบบและเข้าถึงได้ผ่าน HTTP ซึ่งหมายความว่าเรายังสามารถใช้รันไทม์ Edge เช่น Vercel เพื่อรันโค้ดของเราใกล้กับผู้ใช้โดยมีเวลาแฝงขั้นต่ำ

QStash คืออะไร

QStash เป็นโซลูชันการส่งข้อความและกำหนดเวลาที่ใช้ HTTP สำหรับรันไทม์แบบไร้เซิร์ฟเวอร์และ Edge . กล่าวอีกนัยหนึ่ง ช่วยให้คุณสามารถรันงาน CRON โดยการส่งคำขอ HTTP .

งาน CRON เป็นวิธีที่ยอดเยี่ยมในการจัดตารางเวลางานให้ทำงานตามเวลาที่กำหนด งาน CRON นี้อาจใช้เวลามากเท่าที่ต้องการในการทำงานโดยไม่ส่งผลกระทบต่อประสิทธิภาพของแอปพลิเคชันหรือผู้ใช้ปลายทางของคุณ

เป้าหมายของงาน CRON ของเราในบทความนี้คือการซิงค์สถานะโควต้าผู้ใช้จาก Redis ไปยังฐานข้อมูลของเรา เราจะทำให้งานนี้ทำงานทุกชั่วโมง .

การสร้างจุดสิ้นสุดงาน CRON ด้วย QStash

ต่อไปนี้คือสรุปโดยย่อของบทความก่อนหน้านี้เกี่ยวกับวิธีที่เราจัดการสถานะโควต้าผู้ใช้ใน Redis:

// Key stored in Redis. A key is created for each user, and made unique by their ID.
const quotaKey = `user:${userId}:quota`;
 
// Call the INCR command to increment the value of the key by 1.
const quota = await redis.incr(quotaKey);
 
// If the value of the key is 1, it means the key has been created.
// We can set an expiration date of 24 hours to this key by using the EXPIRE command.
if (quota === 1) {
 await redis.expire(quotaKey, 60 * 60 * 24);
}

ด้วยโค้ดนี้ ตอนนี้เราสามารถสร้างจุดสิ้นสุดงาน CRON โดยใช้ QStash ได้แล้ว ตำแหน่งข้อมูลงาน CRON ของเราจะถูกทริกเกอร์ที่ URL 07 .

มาสร้างไฟล์ใหม่สำหรับปลายทาง Next.js ของเรา:

touch pages/api/cron/update-usage.ts

จากนั้น เราต้องการให้แน่ใจว่ามีเพียง QStash เท่านั้นที่สามารถทริกเกอร์ตำแหน่งข้อมูลนี้ได้ นี่คือสิ่งที่ 19 จัดการสำหรับเรา หากเราไม่ทำเช่นนี้ ใครๆ ก็สามารถ มีศักยภาพ ได้ ทริกเกอร์ตำแหน่งข้อมูลงาน CRON ซึ่งอาจนำไปสู่ปัญหาด้านความปลอดภัยได้

มาติดตั้ง 21 กัน :

npm install @upstash/qstash

ตอนนี้เราสามารถมุ่งเน้นไปที่โค้ดของจุดสิ้นสุดงาน CRON ของเราได้แล้ว

ต่อไปนี้เป็นสรุปสั้นๆ เกี่ยวกับสิ่งที่เราจะทำ:

  • รับโควต้าคีย์ของผู้ใช้ทั้งหมดจาก Redis โดยใช้ 38 (การแบ่งหน้าตามเคอร์เซอร์ที่มีประสิทธิภาพ) .
  • สำหรับแต่ละคีย์ที่พบจาก 48 ให้สร้าง 55 อาร์เรย์ของออบเจ็กต์ที่มี ID ผู้ใช้และโควต้า
  • สร้างธุรกรรมสำหรับผู้ใช้แต่ละรายภายใน 63 อาร์เรย์เพื่ออัพเดตโควต้าในฐานข้อมูล ซึ่งทำได้โดยใช้ Prisma
  • ส่งออกฟังก์ชันปลายทางด้วย 78 ฟังก์ชั่นจาก 82 เพื่อให้แน่ใจว่ามีเพียง QStash เท่านั้นที่สามารถทริกเกอร์ตำแหน่งข้อมูลได้

จุดสิ้นสุดของโค้ดแบบเต็มอยู่ที่นี่ ฉันแน่ใจว่าจะแสดงความคิดเห็นในทุกแง่มุมของโค้ด:

// /pages/api/cron/update-usage.ts
import type { NextApiRequest, NextApiResponse } from "next";
 
import { verifySignature } from "@upstash/qstash/nextjs";
 
import prisma from "@/lib/prisma";
 
// Generate an Upstash Redis instance using environment variables.
// Make sure those are defined in your .env file.
const redis = new Redis({
 url: process.env.UPSTASH_REDIS_REST_URL!,
 token: process.env.UPSTASH_REDIS_REST_TOKEN!,
});
 
// Required by `@upstash/qstash`.
export const config = { api: { bodyParser: false } };
 
// Update the usage of every user by pulling the data from the Redis database into the Prisma database.
async function handler(req: NextApiRequest, res: NextApiResponse) {
 // Contains all the keys found during the `SCAN`.
 const keys: string[] = [];
 // Current position of the cursor, updated after each `SCAN`.
 let cursor = 0;
 
 // Execute the cursor-based pagination using the `SCAN` command.
 // Redis return `0` when the cursor is at the end of the pagination.
 do {
 const [nextCursor, newKeys] = await redis.scan(cursor, {
 // Match the pattern of the keys we want to find, where `*` is a wildcard.
 match: "user:*:quota",
 // Limit the number of keys returned by the `SCAN` command.
 count: 10,
 });
 
 cursor = nextCursor;
 keys.push(...newKeys);
 } while (cursor !== 0);
 
 // Array of objects containing the user's ID and their quota.
 const users: { id: number; quota: number }[] = [];
 
 // Get the usage of each user from Redis based on the keys found.
 for (const key of keys) {
 // A key should be in the format `user:${id}:quota`. Split the key to get the ID.
 const id = key.split(":")[1];
 // Get the current quota of the user using the `GET` command.
 const quota = await redis.get(`user:${id}:quota`);
 
 users.push({ id: parseInt(id, 10), quota });
 }
 
 // Create a transaction for each user to update their quota in the database.
 const promises = users.map((user) =>
 prisma.user.update({
 where: { id: user.id },
 data: { quota: user.quota },
 }),
 );
 
 // Run all transactions.
 await Promise.all(promises);
 
 return res.status(200).json({ message: "OK" });
}
 
// Export the handler with the `verifySignature` function to make sure only
// QStash can authenticate to trigger the CRON job.
export default verifySignature(handler);

ส่วนที่ยากที่สุดเสร็จแล้ว!

การตั้งค่า QStash

ตอนนี้ก่อนที่จะพุชโค้ดของเรา เราจำเป็นต้องตั้งค่า QStash QStash มอบระดับฟรีที่กว้างขวาง เราสามารถใช้คำขอได้มากถึง 500 คำขอ ต่อวัน .

เข้าสู่ระบบภายใน Upstash Console ของคุณแล้วคลิกที่ QStash แท็บ

จากนั้น เรามาสร้างงาน CRON ตามกำหนดการใหม่โดยใช้ ตัวสร้างคำขอ . มันง่ายมากด้วย UI ที่ใช้งานง่าย:

ซิงโครไนซ์สถานะ Redis กับฐานข้อมูลของคุณอย่างราบรื่นโดยใช้ QStash

หลังจากคลิกที่กำหนดการ หากคุณเลื่อนลง คุณจะเห็นงาน CRON ของคุณใน งานที่กำหนดเวลาไว้ ส่วน:

ซิงโครไนซ์สถานะ Redis กับฐานข้อมูลของคุณอย่างราบรื่นโดยใช้ QStash

ขั้นตอนสุดท้าย เราต้องตั้งค่าตัวแปรสภาพแวดล้อม 2 ตัว ในแอปพลิเคชัน Next.js ของเรา ตัวแปรเหล่านั้นจะถูกเพิ่มในตำแหน่งที่แอปพลิเคชัน Next.js ของเราโฮสต์อยู่ ในกรณีนี้คือบน Vercel

ใน ตัวสร้างคำขอ ส่วน มีตัวแปรสภาพแวดล้อม 2 ตัวที่พร้อมให้คัดลอก:

  • 95
  • 107

สิ่งเหล่านี้จำเป็นในการตรวจสอบความถูกต้องของข้อความที่เข้ามา มิฉะนั้นใครก็ตามจะสามารถโทรหาตำแหน่งข้อมูลของคุณได้

ซิงโครไนซ์สถานะ Redis กับฐานข้อมูลของคุณอย่างราบรื่นโดยใช้ QStash

เมื่อคุณมีตัวแปรเหล่านั้นแล้ว คุณสามารถเพิ่มลงในโปรเจ็กต์ Vercel ของคุณได้

ในการดำเนินการนี้ ไปที่โครงการ Vercel ของคุณ คลิกที่ การตั้งค่า จากนั้นไปที่ ตัวแปรสภาพแวดล้อม :

ซิงโครไนซ์สถานะ Redis กับฐานข้อมูลของคุณอย่างราบรื่นโดยใช้ QStash

หลังจากเพิ่มตัวแปรสภาพแวดล้อม 2 ตัวแล้ว ตอนนี้คุณสามารถพุชโค้ดของคุณได้แล้ว

QStash จะทริกเกอร์ตำแหน่งข้อมูลงาน CRON เป็นระยะๆ และอัปเดตการใช้งานของผู้ใช้ทุกคนทุกชั่วโมง

บทสรุป

Upstash มีเครื่องมือมากมายสำหรับสภาพแวดล้อมแบบไร้เซิร์ฟเวอร์ เราสามารถใช้ QStash และ Redis ร่วมกันเพื่อสร้างแอปพลิเคชันที่มีประสิทธิภาพและปรับขนาดได้สำหรับกรณีการใช้งานต่างๆ มากมาย

หากคุณต้องการดูแบบสด ระบบเดียวกันนี้ได้ถูกนำมาใช้กับ fastsheet ซึ่งเป็นเครื่องมือที่จะเปลี่ยนสเปรดชีตของคุณให้เป็น API