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

อนุกรมเวลาใน Redis พร้อม Streams

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

สตรีม:โครงสร้างข้อมูล Redis ใหม่

Redis Streams แสดงถึงอนุกรมเวลาของคู่คีย์-ค่าที่ต่อท้ายเท่านั้น

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

ลูกค้าที่อ่านข้อมูลสามารถบล็อกขณะฟังข้อมูลใหม่ที่เข้ามา สามารถรักษา “บุ๊กมาร์ก” ของข้อความสุดท้ายที่อ่านสำหรับการประมวลผลแบบกลุ่ม หรือจัดเป็น “กลุ่มผู้บริโภค” ที่ซับซ้อนมากขึ้นสำหรับการแชร์ปริมาณงานและรับทราบข้อความ

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

สำหรับตัวอย่างโค้ด เราจะใช้ไคลเอ็นต์ theioredis สำหรับ node.js:

var Redis = require('ioredis');
var redis = new Redis();

กำลังส่งข้อมูลไปยังสตรีม

สตรีมเป็นแบบต่อท้ายเท่านั้น ดังนั้นรายละเอียดเพียงอย่างเดียวที่คุณต้องการคือชื่อของคีย์ Redis ที่คุณต้องการเขียนถึง และชุดของคู่คีย์-ค่าของคุณ

ฉันจะบันทึกการวัดจากเซ็นเซอร์คุณภาพอากาศ โดยส่งสตรีมคู่คีย์-ค่าไปยัง site:pdx คีย์ - โดยเฉพาะฉันกำลังส่งดัชนีคุณภาพอากาศในปัจจุบันและอุณหภูมิเป็นเซลเซียส:

redis.xadd('site:pdx', '*',
           'aqi', 37,
           'tempc', 5.1).then(function(id) {
  console.log("id:", id);
});

> 1527974818120-0

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

จัดหา * เป็นอาร์กิวเมนต์ที่สองในคำสั่งเขียน ดังที่แสดงไว้ด้านบน ทำให้ Redis รู้ว่าจะจัดเก็บข้อมูลด้วยการประทับเวลาของตัวเอง

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

การอ่านอย่างง่าย

เมื่อค่าบางค่าอยู่ในสตรีม คุณสามารถดึงช่วงของค่าโดยการจัดหาช่วงของ ID หรือการประทับเวลา แอปนี้สามารถใช้ได้โดยแอปที่แสดงการอ่านค่าเมตริกคุณภาพอากาศล่าสุดของฉันบนกราฟ:

redis.xrange('site:pdx',
             '1527974818120-0',
             '+',
             'COUNT', 5).then(function(resp) {

  // resp now holds 5 readings, pass them to the open graph:
  // console.log(resp);
});

> [ [ '1543947167906-0', [ 'aqi', '31', 'tempc', '5.1' ] ],
> [ '1543947168312-0', [ 'aqi', '31', 'tempc', '5.3' ] ],
> [ '1543947168901-0', [ 'aqi', '31', 'tempc', '5.4' ] ],
> [ '1543947170033-0', [ 'aqi', '31', 'tempc', '5.4' ] ],
> [ '1543947171460-0', [ 'aqi', '31', 'tempc', '5.6' ] ] ]

ช่วงของตัวเลขสามารถสุ่มตัวอย่างได้จากทุกที่ในสตรีม ซึ่งช่วยให้ระบบสร้างกราฟสามารถสืบค้นข้อมูลย้อนหลังได้โดยไม่ต้องมีบทลงโทษด้านประสิทธิภาพ

การบล็อกและการสำรวจ

ช่วงการสืบค้นข้อมูลมีประโยชน์สำหรับกราฟและการตรวจสอบประวัติ แต่บางครั้งคุณต้องการสร้างระบบที่สามารถตอบสนองทันทีต่อข้อมูลที่เข้ามา - สตรีม Redis เหมาะอย่างยิ่งสำหรับสิ่งนี้เช่นกัน โดยใช้ XREAD :

redis.xread('BLOCK', 10000,
            'STREAMS', 'site:pdx', '$').then(function(resp) {

  // close the windows if aqi > 50
  console.log(resp);
});

การดำเนินการบล็อกเช่นนี้จะรอจนกว่าข้อมูลจะเข้ามาหรือจนกว่าจะหมดเวลา (1,000 มิลลิวินาทีที่นี่) ดังนั้นเพื่อรักษาโพลแบบต่อเนื่อง ให้คุณบล็อกตามตัวอย่างด้านบนจนกว่าข้อมูลจะพร้อมใช้งาน และเรียกง่ายๆ ว่า XREAD คำสั่งอีกครั้งทุกครั้งหลังจากได้รับข้อมูลหรือคำสั่งหมดเวลา

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

ในกรณีข้างต้น ฉันแค่ต้องการข้อมูลใดก็ตามที่เข้ามาในสตรีม เลยใช้โทเค็นพิเศษ '$' เพื่อระบุว่า "ข้อมูลใหม่เท่านั้น"; คำสั่งมีลักษณะแตกต่างกันเล็กน้อยกับ ID ที่ให้มา:

redis.xread('BLOCK', 10000,
            'STREAMS', 'site:pdx', '1543947171460-0');

คุณยังอ่านสตรีมต่างๆ ได้พร้อมกัน โดยคืนค่าจากสตรีมแรกที่รับข้อมูล:

redis.xread('BLOCK', 10000,
            'STREAMS',
              'site:pdx', 'site:global',
              '1543947171460-0', '$');

ในตัวอย่างนี้ คำสั่งจะส่งคืนเมื่อมีข้อมูลใด ๆ ที่ใหม่กว่า ID1543947171460-0 เขียนใน site:pdx หรือเมื่อ ใดๆ ข้อมูลใหม่ถูกเขียนบน site:global .

ประสานงานผู้บริโภค

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

การอ้างอิงด่วนสำหรับคำสั่งสตรีม

มีคำสั่ง Redis ใหม่มากมายสำหรับสตรีม! นี่คือข้อมูลอ้างอิงโดยย่อ ดูรายละเอียดเพิ่มเติมได้ในเอกสารอย่างเป็นทางการ

คำสั่งง่ายๆ:

  • XADD:เพิ่มรายการ (กลุ่มของคู่คีย์-ค่า) ไปยังสตรีม
  • XRANGE และ XREVRANGE:เลือกช่วงหรือวนซ้ำในรายการสตรีม
  • XREAD:ดึงไอเท็มที่ใหม่กว่า ID บางตัว (บล็อกหรือไม่ก็ได้)
  • XTRIM:ทิ้งรายการเก่าเพื่อตัดกระแส
  • XDEL:ลบรายการเฉพาะออกจากสตรีม
  • XLEN:นับรายการในสตรีม
  • XINFO:ตรวจสอบข้อมูลเมตาของสตรีม

คำสั่งกลุ่มผู้บริโภค:

  • XGROUP:สร้าง ลบ หรือรีเซ็ตกลุ่มผู้บริโภค และนำสมาชิกออก
  • XREADGROUP:เหมือน XREAD (ด้านบน) แต่รับข้อความโดยใช้กลุ่มผู้บริโภค
  • XPENDING:ตรวจสอบข้อความที่ส่งถึงกลุ่มผู้บริโภคแต่ไม่ตอบรับ
  • XACK:รับทราบข้อความสำหรับกลุ่มผู้บริโภค ลบออกจากรายการที่รอดำเนินการ
  • XCLAIM:รับช่วงต่อข้อความจากผู้บริโภคที่เสียชีวิต

กรณีการใช้งาน

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

สตรีมยังเหมาะสำหรับใช้ในแอปพลิเคชันที่เคยใช้โครงสร้างข้อมูล Redis อื่นมาก่อน แอปพลิเคชันการจัดคิว เช่น Celery และ Sidekiq สามารถใช้ประโยชน์จากกลุ่มผู้บริโภคของ Streams ในการตรวจสอบใบตอบรับการอ่านด้วยวิธี Redis-native มีบล็อกโพสต์มากมายที่สาธิตแอปแชทง่ายๆ โดยใช้ Redis pubsub ซึ่งสามารถปรับปรุงให้มีประสิทธิภาพมากขึ้นด้วย Redis Streams เนื่องจาก pubsub จะไม่เก็บข้อความหลังจากที่เผยแพร่ไปยังไคลเอ็นต์แล้ว

พร้อมที่จะลองหรือยัง

คุณสามารถลองสตรีม Redis บนเซิร์ฟเวอร์ RedisGreen ใหม่ได้ด้วยการคลิกเพียงไม่กี่ครั้ง