詳解Redis中的List類型
本系列將和大家分享Redis分布式緩存,本章主要簡單介紹下Redis中的List類型,以及如何使用Redis解決博客數(shù)據(jù)分頁、生產(chǎn)者消費(fèi)者模型和發(fā)布訂閱等問題。
Redis List的實(shí)現(xiàn)為一個(gè)雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內(nèi)存開銷,Redis內(nèi)部的很多實(shí)現(xiàn),包括發(fā)送緩沖隊(duì)列等也都是用這個(gè)數(shù)據(jù)結(jié)構(gòu)。
List類型主要用于隊(duì)列和棧,先進(jìn)先出,后進(jìn)先出等。
存儲形式:key--LinkList<value>
首先先給大家Show一波Redis中與List類型相關(guān)的API:
using System; using System.Collections.Generic; using ServiceStack.Redis; namespace TianYa.Redis.Service { /// <summary> /// Redis List的實(shí)現(xiàn)為一個(gè)雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內(nèi)存開銷, /// Redis內(nèi)部的很多實(shí)現(xiàn),包括發(fā)送緩沖隊(duì)列等也都是用這個(gè)數(shù)據(jù)結(jié)構(gòu)。 /// </summary> public class RedisListService : RedisBase { #region Queue隊(duì)列(先進(jìn)先出) /// <summary> /// 入隊(duì) /// </summary> /// <param name="listId">集合Id</param> /// <param name="value">入隊(duì)的值</param> public void EnqueueItemOnList(string listId, string value) { base._redisClient.EnqueueItemOnList(listId, value); } /// <summary> /// 出隊(duì) /// </summary> /// <param name="listId">集合Id</param> /// <returns>出隊(duì)的值</returns> public string DequeueItemFromList(string listId) { return base._redisClient.DequeueItemFromList(listId); } /// <summary> /// 出隊(duì)(阻塞) /// </summary> /// <param name="listId">集合Id</param> /// <param name="timeOut">阻塞時(shí)間(超時(shí)時(shí)間)</param> /// <returns>出隊(duì)的值</returns> public string BlockingDequeueItemFromList(string listId, TimeSpan? timeOut) { return base._redisClient.BlockingDequeueItemFromList(listId, timeOut); } /// <summary> /// 從多個(gè)list中出隊(duì)(阻塞) /// </summary> /// <param name="listIds">集合Id</param> /// <param name="timeOut">阻塞時(shí)間(超時(shí)時(shí)間)</param> /// <returns>返回出隊(duì)的 listId & Item</returns> public ItemRef BlockingDequeueItemFromLists(string[] listIds, TimeSpan? timeOut) { return base._redisClient.BlockingDequeueItemFromLists(listIds, timeOut); } #endregion Queue隊(duì)列(先進(jìn)先出) #region Stack棧(后進(jìn)先出) /// <summary> /// 入棧 /// </summary> /// <param name="listId">集合Id</param> /// <param name="value">入棧的值</param> public void PushItemToList(string listId, string value) { base._redisClient.PushItemToList(listId, value); } /// <summary> /// 入棧,并設(shè)置過期時(shí)間 /// </summary> /// <param name="listId">集合Id</param> /// <param name="value">入棧的值</param> /// <param name="expireAt">過期時(shí)間</param> public void PushItemToList(string listId, string value, DateTime expireAt) { base._redisClient.PushItemToList(listId, value); base._redisClient.ExpireEntryAt(listId, expireAt); } /// <summary> /// 入棧,并設(shè)置過期時(shí)間 /// </summary> /// <param name="listId">集合Id</param> /// <param name="value">入棧的值</param> /// <param name="expireIn">過期時(shí)間</param> public void PushItemToList(string listId, string value, TimeSpan expireIn) { base._redisClient.PushItemToList(listId, value); base._redisClient.ExpireEntryIn(listId, expireIn); } /// <summary> /// 出棧 /// </summary> /// <param name="listId">集合Id</param> /// <returns>出棧的值</returns> public string PopItemFromList(string listId) { return base._redisClient.PopItemFromList(listId); } /// <summary> /// 出棧(阻塞) /// </summary> /// <param name="listId">集合Id</param> /// <param name="timeOut">阻塞時(shí)間(超時(shí)時(shí)間)</param> /// <returns>出棧的值</returns> public string BlockingPopItemFromList(string listId, TimeSpan? timeOut) { return base._redisClient.BlockingPopItemFromList(listId, timeOut); } /// <summary> /// 從多個(gè)list中出棧一個(gè)值(阻塞) /// </summary> /// <param name="listIds">集合Id</param> /// <param name="timeOut">阻塞時(shí)間(超時(shí)時(shí)間)</param> /// <returns>返回出棧的 listId & Item</returns> public ItemRef BlockingPopItemFromLists(string[] listIds, TimeSpan? timeOut) { return base._redisClient.BlockingPopItemFromLists(listIds, timeOut); } /// <summary> /// 從fromListId集合出棧并入棧到toListId集合 /// </summary> /// <param name="fromListId">出棧集合Id</param> /// <param name="toListId">入棧集合Id</param> /// <returns>返回移動的值</returns> public string PopAndPushItemBetweenLists(string fromListId, string toListId) { return base._redisClient.PopAndPushItemBetweenLists(fromListId, toListId); } /// <summary> /// 從fromListId集合出棧并入棧到toListId集合(阻塞) /// </summary> /// <param name="fromListId">出棧集合Id</param> /// <param name="toListId">入棧集合Id</param> /// <param name="timeOut">阻塞時(shí)間(超時(shí)時(shí)間)</param> /// <returns>返回移動的值</returns> public string BlockingPopAndPushItemBetweenLists(string fromListId, string toListId, TimeSpan? timeOut) { return base._redisClient.BlockingPopAndPushItemBetweenLists(fromListId, toListId, timeOut); } #endregion Stack棧(后進(jìn)先出) #region 賦值 /// <summary> /// 向list頭部添加value值 /// </summary> public void PrependItemToList(string listId, string value) { base._redisClient.PrependItemToList(listId, value); } /// <summary> /// 向list頭部添加value值,并設(shè)置過期時(shí)間 /// </summary> public void PrependItemToList(string listId, string value, DateTime expireAt) { base._redisClient.PrependItemToList(listId, value); base._redisClient.ExpireEntryAt(listId, expireAt); } /// <summary> /// 向list頭部添加value值,并設(shè)置過期時(shí)間 /// </summary> public void PrependItemToList(string listId, string value, TimeSpan expireIn) { base._redisClient.PrependItemToList(listId, value); base._redisClient.ExpireEntryIn(listId, expireIn); } /// <summary> /// 向list中添加value值 /// </summary> public void AddItemToList(string listId, string value) { base._redisClient.AddItemToList(listId, value); } /// <summary> /// 向list中添加value值,并設(shè)置過期時(shí)間 /// </summary> public void AddItemToList(string listId, string value, DateTime expireAt) { base._redisClient.AddItemToList(listId, value); base._redisClient.ExpireEntryAt(listId, expireAt); } /// <summary> /// 向list中添加value值,并設(shè)置過期時(shí)間 /// </summary> public void AddItemToList(string listId, string value, TimeSpan expireIn) { base._redisClient.AddItemToList(listId, value); base._redisClient.ExpireEntryIn(listId, expireIn); } /// <summary> /// 向list中添加多個(gè)value值 /// </summary> public void AddRangeToList(string listId, List<string> values) { base._redisClient.AddRangeToList(listId, values); } /// <summary> /// 向list中添加多個(gè)value值,并設(shè)置過期時(shí)間 /// </summary> public void AddRangeToList(string listId, List<string> values, DateTime expireAt) { base._redisClient.AddRangeToList(listId, values); base._redisClient.ExpireEntryAt(listId, expireAt); } /// <summary> /// 向list中添加多個(gè)value值,并設(shè)置過期時(shí)間 /// </summary> public void AddRangeToList(string listId, List<string> values, TimeSpan expireIn) { base._redisClient.AddRangeToList(listId, values); base._redisClient.ExpireEntryIn(listId, expireIn); } #endregion 賦值 #region 獲取值 /// <summary> /// 獲取指定list中包含的數(shù)據(jù)數(shù)量 /// </summary> public long GetListCount(string listId) { return base._redisClient.GetListCount(listId); } /// <summary> /// 獲取指定list中包含的所有數(shù)據(jù)集合 /// </summary> public List<string> GetAllItemsFromList(string listId) { return base._redisClient.GetAllItemsFromList(listId); } /// <summary> /// 獲取指定list中下標(biāo)從startingFrom到endingAt的值集合 /// </summary> public List<string> GetRangeFromList(string listId, int startingFrom, int endingAt) { return base._redisClient.GetRangeFromList(listId, startingFrom, endingAt); } #endregion 獲取值 #region 刪除 /// <summary> /// 移除指定list中,listId/value,與參數(shù)相同的值,并返回移除的數(shù)量 /// </summary> public long RemoveItemFromList(string listId, string value) { return base._redisClient.RemoveItemFromList(listId, value); } /// <summary> /// 從指定list的尾部移除一個(gè)數(shù)據(jù),并返回移除的數(shù)據(jù) /// </summary> public string RemoveEndFromList(string listId) { return base._redisClient.RemoveEndFromList(listId); } /// <summary> /// 從指定list的頭部移除一個(gè)數(shù)據(jù),并返回移除的數(shù)據(jù) /// </summary> public string RemoveStartFromList(string listId) { return base._redisClient.RemoveStartFromList(listId); } #endregion 刪除 #region 其它 /// <summary> /// 清理數(shù)據(jù),保持list長度 /// </summary> /// <param name="listId">集合Id</param> /// <param name="keepStartingFrom">保留起點(diǎn)</param> /// <param name="keepEndingAt">保留終點(diǎn)</param> public void TrimList(string listId, int keepStartingFrom, int keepEndingAt) { base._redisClient.TrimList(listId, keepStartingFrom, keepEndingAt); } #endregion 其它 #region 發(fā)布訂閱 /// <summary> /// 發(fā)布 /// </summary> /// <param name="channel">頻道</param> /// <param name="message">消息</param> public void Publish(string channel, string message) { base._redisClient.PublishMessage(channel, message); } /// <summary> /// 訂閱 /// </summary> /// <param name="channel">頻道</param> /// <param name="actionOnMessage"></param> public void Subscribe(string channel, Action<string, string, IRedisSubscription> actionOnMessage) { var subscription = base._redisClient.CreateSubscription(); subscription.OnSubscribe = c => { Console.WriteLine($"訂閱頻道{c}"); Console.WriteLine(); }; //取消訂閱 subscription.OnUnSubscribe = c => { Console.WriteLine($"取消訂閱 {c}"); Console.WriteLine(); }; subscription.OnMessage += (c, s) => { actionOnMessage(c, s, subscription); }; Console.WriteLine($"開始啟動監(jiān)聽 {channel}"); subscription.SubscribeToChannels(channel); //blocking } /// <summary> /// 取消訂閱 /// </summary> /// <param name="channel">頻道</param> public void UnSubscribeFromChannels(string channel) { var subscription = base._redisClient.CreateSubscription(); subscription.UnSubscribeFromChannels(channel); } #endregion 發(fā)布訂閱 } }
使用如下:
/// <summary> /// Redis List的實(shí)現(xiàn)為一個(gè)雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內(nèi)存開銷, /// Redis內(nèi)部的很多實(shí)現(xiàn),包括發(fā)送緩沖隊(duì)列等也都是用這個(gè)數(shù)據(jù)結(jié)構(gòu)。 /// 隊(duì)列/棧/生產(chǎn)者消費(fèi)者模型/發(fā)布訂閱 /// </summary> public static void ShowList() { using (RedisListService service = new RedisListService()) { service.FlushAll(); service.AddItemToList("article", "張三"); service.AddItemToList("article", "李四"); service.AddItemToList("article", "王五"); service.PrependItemToList("article", "趙六"); service.PrependItemToList("article", "錢七"); var result1 = service.GetAllItemsFromList("article"); //一次性獲取所有的數(shù)據(jù) var result2 = service.GetRangeFromList("article", 0, 3); //可以按照添加順序自動排序,而且可以分頁獲取 Console.WriteLine($"result1={JsonConvert.SerializeObject(result1)}"); Console.WriteLine($"result2={JsonConvert.SerializeObject(result2)}"); Console.WriteLine("====================================================="); //棧:后進(jìn)先出 service.FlushAll(); service.PushItemToList("article", "張三"); //入棧 service.PushItemToList("article", "李四"); service.PushItemToList("article", "王五"); service.PushItemToList("article", "趙六"); service.PushItemToList("article", "錢七"); for (int i = 0; i < 5; i++) { Console.WriteLine(service.PopItemFromList("article")); //出棧 } Console.WriteLine("====================================================="); //隊(duì)列:先進(jìn)先出,生產(chǎn)者消費(fèi)者模型 //MSMQ---RabbitMQ---ZeroMQ---RedisList 學(xué)習(xí)成本、技術(shù)成本 service.FlushAll(); service.EnqueueItemOnList("article", "張三"); //入隊(duì) service.EnqueueItemOnList("article", "李四"); service.EnqueueItemOnList("article", "王五"); service.EnqueueItemOnList("article", "趙六"); service.EnqueueItemOnList("article", "錢七"); for (int i = 0; i < 5; i++) { Console.WriteLine(service.DequeueItemFromList("article")); //出隊(duì) } //分布式緩存,多服務(wù)器都可以訪問到,多個(gè)生產(chǎn)者,多個(gè)消費(fèi)者,任何產(chǎn)品只被消費(fèi)一次 } }
運(yùn)行結(jié)果如下所示:
下面我們就來看下如何使用上面的API來解決一些具體的問題:
一、博客數(shù)據(jù)分頁
應(yīng)用場景:
博客網(wǎng)站每天新增的隨筆和文章可能都是幾千幾萬的,表里面是幾千萬數(shù)據(jù)。首頁要展示最新的隨筆,還有前20頁是很多人訪問的。
這種情況下如果首頁分頁數(shù)據(jù)每次都去查詢數(shù)據(jù)庫,那么就會有很大的性能問題。
解決方案:
每次寫入數(shù)據(jù)庫的時(shí)候,把 ID_標(biāo)題 寫入到Redis的List中(后面搞個(gè)TrimList,只要最近的200個(gè))。
這樣的話用戶每次刷頁面就不需要去訪問數(shù)據(jù)庫了,直接讀取Redis中的數(shù)據(jù)。
第一頁(當(dāng)然也可以是前幾頁)的時(shí)候可以不體現(xiàn)總記錄數(shù),只拿最新數(shù)據(jù)展示,這樣就能避免訪問數(shù)據(jù)庫了。
還有一種就是水平分表了,數(shù)據(jù)存到Redis的時(shí)候可以保存 ID_表名稱_標(biāo)題
使用List主要是解決數(shù)據(jù)量大,變化快的數(shù)據(jù)分頁問題。
二八原則:80%的訪問集中在20%的數(shù)據(jù),List里面只用保存大概的量就夠用了。
using TianYa.Redis.Service; namespace MyRedis.Scene { /// <summary> /// 博客數(shù)據(jù)分頁 /// /// 應(yīng)用場景: /// 博客網(wǎng)站每天新增的隨筆和文章可能都是幾千幾萬的,表里面是幾千萬數(shù)據(jù)。首頁要展示最新的隨筆,還有前20頁是很多人訪問的。 /// 這種情況下如果首頁分頁數(shù)據(jù)每次都去查詢數(shù)據(jù)庫,那么就會有很大的性能問題。 /// /// 解決方案: /// 每次寫入數(shù)據(jù)庫的時(shí)候,把 ID_標(biāo)題 寫入到Redis的List中(后面搞個(gè)TrimList,只要最近的200個(gè))。 /// 這樣的話用戶每次刷頁面就不需要去訪問數(shù)據(jù)庫了,直接讀取Redis中的數(shù)據(jù)。 /// 第一頁(當(dāng)然也可以是前幾頁)的時(shí)候可以不體現(xiàn)總記錄數(shù),只拿最新數(shù)據(jù)展示,這樣就能避免訪問數(shù)據(jù)庫了。 /// /// 還有一種就是水平分表了,數(shù)據(jù)存到Redis的時(shí)候可以保存 ID_表名稱_標(biāo)題 /// /// 使用List主要是解決數(shù)據(jù)量大,變化快的數(shù)據(jù)分頁問題。 /// 二八原則:80%的訪問集中在20%的數(shù)據(jù),List里面只用保存大概的量就夠用了。 /// </summary> public class BlogPageList { public static void Show() { using (RedisListService service = new RedisListService()) { service.AddItemToList("newBlog", "10001_IOC容器的實(shí)現(xiàn)原理"); service.AddItemToList("newBlog", "10002_AOP面向切面編程"); service.AddItemToList("newBlog", "10003_行為型設(shè)計(jì)模式"); service.AddItemToList("newBlog", "10004_結(jié)構(gòu)型設(shè)計(jì)模式"); service.AddItemToList("newBlog", "10005_創(chuàng)建型設(shè)計(jì)模式"); service.AddItemToList("newBlog", "10006_GC垃圾回收"); service.TrimList("newBlog", 0, 200); //保留最新的201個(gè)(一個(gè)List最多只能存放2的32次方-1個(gè)) var result1 = service.GetRangeFromList("newBlog", 0, 9); //第一頁 var result2 = service.GetRangeFromList("newBlog", 10, 19); //第二頁 var result3 = service.GetRangeFromList("newBlog", 20, 29); //第三頁 } } } }
二、生產(chǎn)者消費(fèi)者模型
分布式緩存,多服務(wù)器都可以訪問到,多個(gè)生產(chǎn)者,多個(gè)消費(fèi)者,任何產(chǎn)品只被消費(fèi)一次。(使用隊(duì)列實(shí)現(xiàn))
其中一個(gè)(或多個(gè))程序?qū)懭?,另外一個(gè)(或多個(gè))程序讀取消費(fèi)。按照時(shí)間順序,數(shù)據(jù)失敗了還可以放回去下次重試。
下面我們來看個(gè)例子:
Demo中添加了2個(gè)控制臺應(yīng)用程序,分別模擬生產(chǎn)者和消費(fèi)者:
using System; using TianYa.Redis.Service; namespace TianYa.Producer { /// <summary> /// 模擬生產(chǎn)者 /// </summary> class Program { static void Main(string[] args) { Console.WriteLine("生產(chǎn)者程序啟動了。。。"); using (RedisListService service = new RedisListService()) { Console.WriteLine("開始生產(chǎn)test產(chǎn)品"); for (int i = 1; i <= 20; i++) { service.EnqueueItemOnList("test", $"產(chǎn)品test{i}"); } Console.WriteLine("開始生產(chǎn)task產(chǎn)品"); for (int i = 1; i <= 20; i++) { service.EnqueueItemOnList("task", $"產(chǎn)品task{i}"); } Console.WriteLine("模擬生產(chǎn)結(jié)束"); while (true) { Console.WriteLine("************請輸入數(shù)據(jù)************"); string testTask = Console.ReadLine(); service.EnqueueItemOnList("test", testTask); } } } } }
using System; using System.Threading; using TianYa.Redis.Service; namespace TianYa.Consumer { /// <summary> /// 模擬消費(fèi)者 /// </summary> class Program { static void Main(string[] args) { Console.WriteLine("消費(fèi)者程序啟動了。。。"); using (RedisListService service = new RedisListService()) { while (true) { var result = service.BlockingDequeueItemFromLists(new string[] { "test", "task" }, TimeSpan.FromHours(1)); Thread.Sleep(100); Console.WriteLine($"消費(fèi)者消費(fèi)了 {result.Id} {result.Item}"); } } } } }
接下來我們使用.NET Core CLI來啟動2個(gè)消費(fèi)者實(shí)例和1個(gè)生產(chǎn)者實(shí)例,運(yùn)行結(jié)果如下所示:
像這種異步隊(duì)列在項(xiàng)目中有什么價(jià)值呢?
PS:此處事務(wù)是一個(gè)很大問題,真實(shí)項(xiàng)目中需根據(jù)實(shí)際情況決定是否采用異步隊(duì)列。
三、發(fā)布訂閱
發(fā)布訂閱:
發(fā)布一個(gè)數(shù)據(jù),全部的訂閱者都能收到。
觀察者,一個(gè)數(shù)據(jù)源,多個(gè)接收者,只要訂閱了就可以收到的,能被多個(gè)數(shù)據(jù)源共享。
觀察者模式:微信訂閱號---群聊天---數(shù)據(jù)同步。。。
下面我們來看個(gè)小Demo:
/// <summary> /// 發(fā)布訂閱 /// 發(fā)布一個(gè)數(shù)據(jù),全部的訂閱者都能收到。 /// 觀察者,一個(gè)數(shù)據(jù)源,多個(gè)接收者,只要訂閱了就可以收到的,能被多個(gè)數(shù)據(jù)源共享。 /// 觀察者模式:微信訂閱號---群聊天---數(shù)據(jù)同步。。。 /// </summary> public static void ShowPublishAndSubscribe() { Task.Run(() => { using (RedisListService service = new RedisListService()) { service.Subscribe("TianYa", (c, message, iRedisSubscription) => { Console.WriteLine($"注冊{1}{c}:{message},Dosomething else"); if (message.Equals("exit")) iRedisSubscription.UnSubscribeFromChannels("TianYa"); });//blocking } }); Task.Run(() => { using (RedisListService service = new RedisListService()) { service.Subscribe("TianYa", (c, message, iRedisSubscription) => { Console.WriteLine($"注冊{2}{c}:{message},Dosomething else"); if (message.Equals("exit")) iRedisSubscription.UnSubscribeFromChannels("TianYa"); });//blocking } }); Task.Run(() => { using (RedisListService service = new RedisListService()) { service.Subscribe("Twelve", (c, message, iRedisSubscription) => { Console.WriteLine($"注冊{3}{c}:{message},Dosomething else"); if (message.Equals("exit")) iRedisSubscription.UnSubscribeFromChannels("Twelve"); });//blocking } }); using (RedisListService service = new RedisListService()) { Thread.Sleep(1000); service.Publish("TianYa", "TianYa1"); Thread.Sleep(1000); service.Publish("TianYa", "TianYa2"); Thread.Sleep(1000); service.Publish("TianYa", "TianYa3"); Thread.Sleep(1000); service.Publish("Twelve", "Twelve1"); Thread.Sleep(1000); service.Publish("Twelve", "Twelve2"); Thread.Sleep(1000); service.Publish("Twelve", "Twelve3"); Thread.Sleep(1000); Console.WriteLine("**********************************************"); Thread.Sleep(1000); service.Publish("TianYa", "exit"); Thread.Sleep(1000); service.Publish("TianYa", "TianYa6"); Thread.Sleep(1000); service.Publish("TianYa", "TianYa7"); Thread.Sleep(1000); service.Publish("TianYa", "TianYa8"); Thread.Sleep(1000); service.Publish("Twelve", "exit"); Thread.Sleep(1000); service.Publish("Twelve", "Twelve6"); Thread.Sleep(1000); service.Publish("Twelve", "Twelve7"); Thread.Sleep(1000); service.Publish("Twelve", "Twelve8"); Thread.Sleep(1000); Console.WriteLine("結(jié)束"); } }
運(yùn)行結(jié)果如下所示:
至此本文就全部介紹完了,如果覺得對您有所啟發(fā)請記得點(diǎn)個(gè)贊哦!?。?/p>
Demo源碼:
鏈接: https://pan.baidu.com/s/1_kEMCtbf2iT5pLV7irxR5Q 提取碼: v4sr
此文由博主精心撰寫轉(zhuǎn)載請保留此原文鏈接:https://www.cnblogs.com/xyh9039/p/14022264.html
到此這篇關(guān)于詳解Redis中的List類型的文章就介紹到這了,更多相關(guān)Redis List類型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
redis搭建哨兵模式實(shí)現(xiàn)一主兩從三哨兵
本文主要介紹了redis搭建哨兵模式實(shí)現(xiàn)一主兩從三哨兵,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08Satoken+Redis實(shí)現(xiàn)短信登錄、注冊、鑒權(quán)功能
這篇文章主要介紹了Satoken+Redis實(shí)現(xiàn)短信登錄、注冊、鑒權(quán)功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01redis實(shí)現(xiàn)動態(tài)字符串SDS
簡單動態(tài)字符串是Redis的基本數(shù)據(jù)結(jié)構(gòu)之一,用于存儲字符串和整型數(shù)據(jù),本文主要介紹了redis實(shí)現(xiàn)動態(tài)字符串SDS,具有一定的參考價(jià)值,感興趣的可以了解一下2024-04-04Redis大key多key拆分實(shí)現(xiàn)方法解析
這篇文章主要介紹了Redis大key多key拆分實(shí)現(xiàn)方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11Redis中有序集合的內(nèi)部實(shí)現(xiàn)方式的詳細(xì)介紹
本文主要介紹了Redis中有序集合的內(nèi)部實(shí)現(xiàn)方式的詳細(xì)介紹,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03