โดย เมฮุล โมฮัน
Redis เป็นฐานข้อมูลในหน่วยความจำยอดนิยมที่ใช้สำหรับโปรเจ็กต์ที่หลากหลาย เช่น การแคชและการจำกัดอัตรา
ในบล็อกโพสต์นี้ เราจะดูว่าคุณสามารถใช้ Redis เป็นฐานข้อมูลในหน่วยความจำได้อย่างไร ทำไมคุณถึงต้องการใช้ Redis และสุดท้ายเราจะพูดถึงคุณลักษณะที่สำคัญบางประการของฐานข้อมูล เริ่มกันเลย
ฐานข้อมูลในหน่วยความจำคืออะไร
ฐานข้อมูลแบบดั้งเดิมจะเก็บส่วนหนึ่งของฐานข้อมูล (โดยปกติจะเป็นดัชนี "ยอดนิยม" หรือที่มีการเข้าถึงบ่อย) ไว้ในหน่วยความจำเพื่อให้เข้าถึงได้รวดเร็วยิ่งขึ้น และส่วนที่เหลือของฐานข้อมูลจะอยู่บนดิสก์ ป>
ในทางกลับกัน Redis มุ่งเน้นไปที่ความหน่วงและการดึงและจัดเก็บข้อมูลอย่างรวดเร็ว ดังนั้นจึงทำงานอย่างสมบูรณ์บนหน่วยความจำ (RAM) แทนที่จะเป็นอุปกรณ์จัดเก็บข้อมูล (SSD/HDD) ความเร็วเป็นสิ่งสำคัญ!
Redis เป็นฐานข้อมูลคีย์-ค่า แต่อย่าปล่อยให้มันหลอกคุณให้คิดว่ามันเป็นฐานข้อมูลธรรมดา คุณมีหลายวิธีในการจัดเก็บและเรียกค้นคีย์และค่าเหล่านั้น
ทำไมคุณถึงต้องการ Redis
คุณสามารถใช้ Redis ได้หลายวิธี แต่มีสองเหตุผลหลักที่ฉันนึกถึงได้:
- คุณกำลังสร้างแอปพลิเคชันที่คุณต้องการทำให้เลเยอร์โค้ดของคุณไร้สถานะ ทำไม - เพราะหากโค้ดของคุณไม่มีสถานะ ก็สามารถปรับขนาดได้ในแนวนอน ดังนั้น คุณสามารถใช้ Redis เป็นระบบจัดเก็บข้อมูลส่วนกลางและให้โค้ดของคุณจัดการเฉพาะตรรกะ
- คุณกำลังสร้างแอปพลิเคชันที่อาจจำเป็นต้องแชร์ข้อมูลหลายแอป ตัวอย่างเช่น จะเกิดอะไรขึ้นถ้ามีคนพยายามบังคับใช้เว็บไซต์ของคุณที่
06และเมื่อคุณตรวจพบแล้ว คุณยังต้องการบล็อกพวกเขาที่19? Redis ช่วยให้บริการที่ขาดการเชื่อมต่อ/เชื่อมต่อแบบหลวมๆ ของคุณใช้พื้นที่หน่วยความจำร่วมกัน
Redis นั้นค่อนข้างง่ายในการเรียนรู้ เนื่องจากมีคำสั่งเพียงไม่กี่คำสั่งที่คุณจำเป็นต้องรู้ ในส่วนถัดไป เราจะกล่าวถึงแนวคิดหลักบางประการของ Redis และคำสั่งทั่วไปที่เป็นประโยชน์
Redis CLI
Redis มี CLI ซึ่งเป็นเวอร์ชัน REPL ของบรรทัดคำสั่ง สิ่งที่คุณเขียนจะถูกประเมิน ป>
รูปภาพด้านบนแสดงวิธีการทำ 25 แบบง่ายๆ หรือสวัสดีชาวโลกใน Redis ในหนึ่งในแบบฝึกหัดหลักสูตร Redis ที่แสนจะเลวร้ายของฉัน (หลักสูตรจะลิงก์อยู่ที่ตอนท้ายหากคุณต้องการลองดู)
Redis REPL นี้มีประโยชน์มากเมื่อคุณทำงานกับฐานข้อมูลในแอปพลิเคชันและต้องการดูคีย์บางรายการหรือสถานะของ Redis อย่างรวดเร็ว
คำสั่ง Redis ทั่วไป
ลองใช้คำสั่งทั่วไปบน Redis CLI ในหลักสูตร codedamn ป>
ต่อไปนี้เป็นคำสั่งบางส่วนที่ใช้กันทั่วไปใน Redis เพื่อช่วยให้คุณเรียนรู้เพิ่มเติมเกี่ยวกับวิธีการทำงาน:
ตั้งค่า
SET อนุญาตให้คุณตั้งค่าคีย์เป็นค่าใน Redis
นี่คือตัวอย่างวิธีการทำงาน:
SET mehul "developer from india"
นี่เป็นการตั้งค่าคีย์ 39 เป็นค่า 46 .
รับ
GET อนุญาตให้คุณรับคีย์ที่คุณตั้งไว้
นี่คือไวยากรณ์:
GET mehul
สิ่งนี้จะส่งคืนสตริง "developer from india" ตามที่เรากำหนดไว้ข้างต้น
SETNX
คีย์นี้จะตั้งค่าเฉพาะในกรณีที่ไม่มีคีย์ คำสั่งนี้มีกรณีการใช้งานหลายประการ รวมถึงการไม่เขียนทับค่าของคีย์ที่อาจมีอยู่แล้วโดยไม่ตั้งใจ
นี่คือวิธีการทำงาน:
SET key1 value1
SETNX key1 value2
SETNX key2 value2
หลังจากรันตัวอย่างนี้ 57 ของคุณ จะมีค่า 62 และ 70รหัส> เป็น 89 . เนื่องจากคำสั่งที่สองจะไม่มีผลเป็น 98 มีอยู่แล้ว
เอ็มเซต
MSET ก็เหมือนกับ SET แต่คุณสามารถตั้งค่าหลายคีย์พร้อมกันได้ในคำสั่งเดียว นี่คือวิธีการทำงาน:
MSET key1 "value1" key2 "value2" key3 "value3"
ตอนนี้เรากำลังใช้
ดังนั้นสิ่งหนึ่งที่คุณสามารถทำได้คือเสนอราคาของคุณโดยใช้เครื่องหมายคำพูดคู่เสมอ และปล่อยคีย์ของคุณโดยไม่มีเครื่องหมายคำพูด (หากเป็นชื่อคีย์ที่ถูกต้องโดยไม่มีเครื่องหมายคำพูด)
MGET คล้ายกับ GET แต่สามารถส่งคืนค่าหลายค่าพร้อมกันได้ เช่นนี้:
ซึ่งจะคืนค่าสี่ค่าเป็นอาร์เรย์:
คำสั่งนี้จะลบคีย์ – ง่ายพอใช่ไหม
นี่คือตัวอย่าง:
คุณสามารถใช้สองคำสั่งนี้เพื่อเพิ่มหรือลดคีย์ซึ่งเป็นตัวเลข มันมีประโยชน์มากและคุณจะใช้มันบ่อยมาก เพราะ Redis สามารถดำเนินการสองอย่างในหนึ่งเดียว – GET key และ SET key to key + 1
วิธีนี้จะหลีกเลี่ยงการย้อนกลับไปยังแอปพลิเคชันหลักของคุณ และทำให้การดำเนินการยังปลอดภัยที่จะดำเนินการโดยไม่ต้องใช้ธุรกรรม (เพิ่มเติมเกี่ยวกับเรื่องนี้ในภายหลัง)
นี่คือวิธีการทำงาน:
คำสั่ง EXPIRE ใช้เพื่อตั้งเวลาหมดอายุให้กับคีย์ ในทางเทคนิคแล้ว ไม่ใช่ตัวจับเวลา แต่เป็นการประทับเวลาการฆ่าที่เกินกว่านั้น ซึ่งคีย์จะส่งกลับค่าว่างเสมอ เว้นแต่จะมีการตั้งค่าอีกครั้ง
คำสั่งนี้สามารถใช้เพื่อเรียนรู้ว่ากุญแจต้องใช้งานได้นานเท่าใด
ตัวอย่าง:
แล้วเราจะเรียนรู้อะไรจากโค้ดนี้ได้บ้าง
คุณสามารถดำเนินการ SET และ หมดอายุ พร้อมด้วย
เช่นนี้:
ในที่นี้ คีย์คือ "คีย์" ค่าคือ "ค่า" และเวลาที่ใช้งาน (TTL) คือ 10 คีย์นี้จะถูกยกเลิกการตั้งค่าหลังจาก 10 วินาที
ตอนนี้คุณมีความรู้พื้นฐานเกี่ยวกับคำสั่ง Redis พื้นฐานและวิธีการทำงานของ CLI แล้ว มาสร้างโปรเจ็กต์สักสองสามโปรเจ็กต์และใช้เครื่องมือเหล่านั้นในชีวิตจริงกันดีกว่า
โปรเจ็กต์นี้เกี่ยวข้องกับการตั้งค่าระบบแคช API ด้วย Redis ซึ่งคุณแคชผลลัพธ์จากเซิร์ฟเวอร์บุคคลที่สามและใช้งานเป็นระยะเวลาหนึ่ง ป>
สิ่งนี้มีประโยชน์เพื่อที่คุณจะได้ไม่ถูกจำกัดอัตราโดยบุคคลที่สามนั้น นอกจากนี้ การแคชยังช่วยเพิ่มความเร็วให้กับเว็บไซต์ของคุณ ดังนั้นหากคุณใช้งานอย่างถูกต้อง ก็จะได้ประโยชน์ทั้งสองฝ่าย
คุณสามารถสร้างโปรเจ็กต์นี้แบบโต้ตอบได้บน codedamn ภายในเบราว์เซอร์โดยใช้ Node.js หากคุณสนใจ คุณสามารถลองใช้แล็บแคช API ได้ฟรี
หากคุณสนใจเฉพาะโซลูชัน (และไม่ได้สร้างด้วยตนเอง) นี่คือวิธีการทำงานของตรรกะหลักใน Node.js:
มาดูกันว่าเกิดอะไรขึ้นที่นี่:
นี่คือซอร์สโค้ดแบบเต็ม:
โปรเจ็กต์นี้เกี่ยวข้องกับการจำกัดอัตราการปลายทางบางอย่างเพื่อปกป้องจากผู้ไม่ประสงค์ดี จากนั้นจึงบล็อกไม่ให้พวกเขาเข้าถึง API นั้นๆ ป>
สิ่งนี้มีประโยชน์มากสำหรับการเข้าสู่ระบบและตำแหน่งข้อมูล API ที่ละเอียดอ่อน ซึ่งคุณไม่ต้องการให้บุคคลเดียวเข้าถึงตำแหน่งข้อมูลของคุณด้วยคำขอหลายพันรายการ
เราดำเนินการจำกัดอัตราตามที่อยู่ IP ในแล็บนี้ หากคุณต้องการลองใช้ Codelab นี้ คุณสามารถทดลองใช้ได้ฟรีที่ Codedamn
หากคุณสนใจเฉพาะโซลูชัน (และไม่ได้สร้างด้วยตนเอง) นี่คือวิธีการทำงานของตรรกะหลักใน Node.js:
มาทำความเข้าใจบล็อกโค้ดนี้:
นี่คือวิธีแก้ปัญหาแบบเต็ม:
Redis เป็นมากกว่าสิ่งที่เราได้เรียนรู้มาจนถึงตอนนี้ แต่ข้อดีคือเราได้เรียนรู้มากพอที่จะเริ่มทำงานกับมันแล้ว! ป>
ในส่วนนี้ เราจะกล่าวถึงปัจจัยพื้นฐาน Redis เพิ่มเติมบางส่วน
Redis ทำงานเป็นกระบวนการแบบเธรดเดียว แม้บนระบบหลายคอร์ที่รองรับมัลติเธรด นี่ไม่ใช่ฝันร้ายด้านประสิทธิภาพ แต่เป็นมาตรการด้านความปลอดภัยต่อการอ่าน/เขียนที่ไม่สอดคล้องกันในสภาพแวดล้อมแบบมัลติเธรด ป>
หาก Redis เป็นแบบมัลติเธรด เพื่อให้มั่นใจถึงความปลอดภัยของเธรดเมื่อเข้าถึงคีย์เดียว ในที่สุดคุณก็จะต้องใช้กลไกการล็อกบางอย่าง ซึ่งอาจทำงานได้แย่กว่าการเข้าถึงแบบเธรดเดี่ยว/ตามลำดับอยู่ดี
แน่นอนว่าคุณไม่สามารถทำทุกอย่างใน Redis ด้วยคำสั่งเดียวได้ แต่คุณสามารถขอให้มันทำบล็อกคำสั่งได้ในคราวเดียว (นั่นคือ ไม่มีใครคุยกับ Redis ในขณะที่กำลังดำเนินการบล็อกนั้น) คุณสามารถทำได้โดยใช้
วิธีการทำงานมีดังนี้:
การดำเนินการทั้งหมดนี้จะดำเนินการในคราวเดียว นั่นคือจะ ไม่ เรียกใช้อะไรก็ได้หลังจาก
Redis มีการรองรับรายการและชุดสำหรับกรณีการใช้งานขั้นสูงเพิ่มเติม คุณยังสามารถใช้ Redis เป็นบริการกระจายเสียงที่คุณเผยแพร่ได้ ไปยังช่องและคนอื่นๆ ที่ ติดตาม ไปที่ช่องเพื่อรับการแจ้งเตือน สิ่งนี้มีประโยชน์มากในสถาปัตยกรรมแบบหลายไคลเอนต์
ฉันหวังว่าคุณจะชอบการแนะนำ Redis นี้ โพสต์ในบล็อกนี้เป็นส่วนหนึ่งของหลักสูตรเชิงโต้ตอบใหม่ของ Codedamn:การแคช Redis + Node.js ซึ่งคุณไม่เพียงแต่เรียนรู้เกี่ยวกับแนวคิดเหล่านี้เท่านั้น แต่ยังฝึกฝนแนวคิดเหล่านี้ได้จากเบราว์เซอร์ของคุณทุกที่ทุกเวลา ป>
อย่าลังเลที่จะทดลองใช้หลักสูตรและแจ้งให้เราทราบว่าคุณคิดอย่างไร คุณสามารถหาฉันได้บน Twitter เพื่อส่งข้อเสนอแนะ :)
เรียนรู้การเขียนโค้ดฟรี หลักสูตรโอเพ่นซอร์สของ freeCodeCamp ช่วยให้ผู้คนมากกว่า 40,000 คนได้งานในตำแหน่งนักพัฒนา เริ่มต้น 101 และ 111รหัส> เป็นคำนำหน้าสำหรับคีย์และค่า แต่ในความเป็นจริงแล้ว เมื่อคุณเขียนโค้ดดังกล่าว เป็นเรื่องง่ายที่จะลืมว่าอะไรคือคีย์และอะไรคือค่าในคำสั่งแบบยาวเช่นนี้ ป> MGET
MGET key1 key2 key3 key4
125 , 139รหัส> , 144รหัส> และ 155รหัส> . เราได้ 164 เป็นโมฆะเพราะเราไม่เคยตั้งค่าไว้เดล
SET key value
GET key # gives you "value"
DEL key
GET key # null
INCR และ DECR
SET favNum 10
INCR favNum # 11
INCR favNum # 12
DECR favNum # 11
หมดอายุ
SET bitcoin 100
EXPIRE bitcoin 10
GET bitcoin # 100
# after 10 seconds
GET bitcoin # null
177รหัส> ใช้หน่วยความจำเพิ่มขึ้นอีกเล็กน้อยเพื่อจัดเก็บคีย์นั้นโดยรวม (เพราะตอนนี้คุณต้องจัดเก็บเมื่อคีย์นั้นจะหมดอายุด้วย) แต่คุณอาจจะไม่สนใจค่าใช้จ่ายนั้นเลยTTL
SET bitcoin 100
TTL bitcoin # -1
TTL somethingelse # -2
EXPIRE bitcoin 5
# wait 2 seconds
TTL bitcoin # returns 3
# after 1 second
GET bitcoin # null
TTL bitcoin # -2
187 หากมีคีย์อยู่แต่ไม่มีวันหมดอายุ190 หากไม่มีคีย์เซเท็กซ์
204 .SETEX key 10 value
โปรเจ็กต์ 1 – สร้างระบบแคช API ด้วย Redis
ดูตัวอย่างห้องแล็บการสร้างระบบแคช API บน codedamn ป>
app.post('/data', async (req, res) => {
const repo = req.body.repo
const value = await redis.get(repo)
if (value) {
// means we got a cache hit
res.json({
status: 'ok',
stars: value
})
return
}
const response = await fetch(`https://api.github.com/repos/${repo}`).then((t) => t.json())
if (response.stargazers_count != undefined) {
await redis.setex(repo, 60, response.stargazers_count)
}
res.json({
status: 'ok',
stars: response.stargazers_count
})
})
215 (ซึ่งเป็นรูปแบบ repo ที่ส่งผ่าน - 226 ) จากแคช Redis ของเรา ถ้ามีก็เยี่ยมเลย! เราจะคืนจำนวนดาวจากแคช Redis ของเรา ซึ่งช่วยให้เราประหยัดเวลาในการเดินทางไปยังเซิร์ฟเวอร์ของ GitHub238 ค่าที่มีการหมดเวลา 60 วินาทีโครงการ 2 - API การจำกัดอัตราด้วย Redis
ดูตัวอย่าง API การจำกัดอัตราด้วย Redis ป>
app.post('/api/route', async (req, res) => {
// add data here
const ip = req.headers['x-forwarded-for'] || req.ip
const reqs = await redis.incr(ip)
await redis.expire(ip, 2)
if (reqs > 15) {
return res.json({
status: 'rate-limited'
})
} else if (reqs > 10) {
return res.json({
status: 'about-to-rate-limit'
})
} else {
res.json({
status: 'ok'
})
}
})
247 header (หรือจะใช้ 253 ก็ได้ ขณะที่เรากำลังใช้ด่วน)266 ช่องที่อยู่ IP หากคีย์ของเราใน Redis ไม่เคยมีอยู่ INCR จะตั้งค่าเป็น 0 และเพิ่มค่าโดยอัตโนมัติ ซึ่งสุดท้ายจะตั้งค่าเป็น 1ข้อมูลเพิ่มเติมเกี่ยวกับ Redis
Redis เป็นแบบเธรดเดียว
ธุรกรรม Redis
270 คำสั่งMULTI
SET hello world
SET yo lo
SET number 1
INCR number
EXPIRE hello 10
EXPIRE yo 5
EXEC
283 และจะเรียกใช้ทุกอย่างพร้อมกันเมื่อเห็น 297 คำสำคัญ.บทสรุป