Redis性能大幅提升之Batch批量讀寫(xiě)詳解
前言
本文主要介紹的是關(guān)于Redis性能提升之Batch批量讀寫(xiě)的相關(guān)內(nèi)容,分享出來(lái)供大家參考學(xué)習(xí),下面來(lái)看看詳細(xì)的介紹:
提示:本文針對(duì)的是StackExchange.Redis
一、問(wèn)題呈現(xiàn)
前段時(shí)間在開(kāi)發(fā)的時(shí)候,遇到了redis批量讀的問(wèn)題,由于在StackExchange.Redis里面我確實(shí)沒(méi)有找到PipeLine命令,找到的是Batch命令,因此對(duì)其用法進(jìn)行了探究一下。
下面的代碼是我之前寫(xiě)的:
public List<StudentEntity> Get(List<int> ids)
{
List<StudentEntity> result = new List<StudentEntity>();
try
{
var db = RedisCluster.conn.GetDatabase();
foreach (int id in ids.Keys)
{
string key = KeyManager.GetKey(id);
var dic = db.HashGetAll(key).ToDictionary(k => k.Name, v => v.Value);
StudentEntity se = new StudentEntity();
if (dic.Keys.Contains(StudentEntityRedisHashKey.id.ToString()))
{
pe.id = FormatUtils.ConvertToInt32(dic[StudentEntityRedisHashKey.id.ToString()], -1);
}
if (dic.Keys.Contains(StudentEntityRedisHashKey.name.ToString()))
{
pe.name= dic[StudentEntityRedisHashKey.name.ToString()];
}
result.Add(se);
}
catch (Exception ex)
{
}
return result;
}
從上面的代碼中可以看出,并不是批量讀,經(jīng)過(guò)性能測(cè)試,性能確實(shí)是要遠(yuǎn)遠(yuǎn)低于用Batch操作,因?yàn)镠ashGetAll方法被執(zhí)行了多次。
下面給出批量方法:
二、解決問(wèn)題方法
具體的用法是:
var batch = db.CreateBatch(); ...//這里寫(xiě)具體批量操作的方法 batch.Execute();
2.1批量寫(xiě):
具體代碼:
public bool InsertBatch(List<StudentEntity> seList)
{
bool result = false;
try
{
var db = RedisCluster.conn.GetDatabase();
var batch = db.CreateBatch();
foreach (var se in seList)
{
string key = KeyManager.GetKey(se.id);
batch.HashSetAsync(key, StudentEntityRedisHashKey.id.ToString(), te.id);
batch.HashSetAsync(key, StudentEntityRedisHashKey.name.ToString(), te.name);
}
batch.Execute();
result = true;
}
catch (Exception ex)
{
}
return result;
}
這個(gè)方法里執(zhí)行的是批量插入學(xué)生實(shí)體數(shù)據(jù),這里只是針對(duì)Hash,其它的也一樣操作。
2.2批量讀:
具體代碼:
public List<StudentEntity> GetBatch(List<int> ids)
{
List<StudentEntity> result = new List<StudentEntity>();
List<Task<StackExchange.Redis.HashEntry[]>> valueList = new List<Task<StackExchange.Redis.HashEntry[]>>();
try
{
var db = RedisCluster.conn.GetDatabase();
var batch = db.CreateBatch();
foreach(int id in ids)
{
string key = KeyManager.GetKey(id);
Task<StackExchange.Redis.HashEntry[]> tres = batch.HashGetAllAsync(key);
valueList.Add(tres);
}
batch.Execute();
foreach(var hashEntry in valueList)
{
var dic = hashEntry.Result.ToDictionary(k => k.Name, v => v.Value);
StudentEntity se= new StudentEntity();
if (dic.Keys.Contains(StudentEntityRedisHashKey.id.ToString()))
{
se.id= FormatUtils.ConvertToInt32(dic[StudentEntityRedisHashKey.id.ToString()], -1);
}
if (dic.Keys.Contains(StudentEntityRedisHashKey.name.ToString()))
{
se.name= dic[StudentEntityRedisHashKey.name.ToString()];
}
result.Add(se);
}
}
catch (Exception ex)
{
}
return result;
}
這個(gè)方法是批量讀取學(xué)生實(shí)體數(shù)據(jù),批量拿到實(shí)體數(shù)據(jù)后,將其轉(zhuǎn)化成我們需要的數(shù)據(jù)。下面給出性能對(duì)比。
2.3性能對(duì)比:
10條數(shù)據(jù),約4-5倍差距:
1000條數(shù)據(jù),約28倍的差距:
隨著數(shù)據(jù)了增多,差距將越來(lái)越大。
三、源碼測(cè)試案例
上面是批量讀寫(xiě)實(shí)體數(shù)據(jù),下面給出StackExchange.Redis源碼測(cè)試案例里的批量讀寫(xiě)寫(xiě)法:
public void TestBatchSent()
{
using (var muxer = Config.GetUnsecuredConnection())
{
var conn = muxer.GetDatabase(0);
conn.KeyDeleteAsync("batch");
conn.StringSetAsync("batch", "batch-sent");
var tasks = new List<Task>();
var batch = conn.CreateBatch();
tasks.Add(batch.KeyDeleteAsync("batch"));
tasks.Add(batch.SetAddAsync("batch", "a"));
tasks.Add(batch.SetAddAsync("batch", "b"));
tasks.Add(batch.SetAddAsync("batch", "c"));
batch.Execute();
var result = conn.SetMembersAsync("batch");
tasks.Add(result);
Task.WhenAll(tasks.ToArray());
var arr = result.Result;
Array.Sort(arr, (x, y) => string.Compare(x, y));
...
}
}
這個(gè)方法里也給出了批量寫(xiě)和讀的操作。
總結(jié)
好了,先說(shuō)到這里了。以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
SpringSession+Redis實(shí)現(xiàn)集群會(huì)話共享的方法
為了保證WEB應(yīng)用的承載能力, 需要對(duì)WEB應(yīng)用進(jìn)行集群處理.這篇文章主要介紹了SpringSession+Redis實(shí)現(xiàn)集群會(huì)話共享的方法,需要的朋友參考下吧2018-08-08
基于Redis6.2.6版本部署Redis?Cluster集群的問(wèn)題
這篇文章主要介紹了基于Redis6.2.6版本部署Redis?Cluster集群,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04
淺談RedisTemplate和StringRedisTemplate的區(qū)別
本文主要介紹了RedisTemplate和StringRedisTemplate的區(qū)別及個(gè)人見(jiàn)解,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
Java實(shí)現(xiàn)多級(jí)緩存的方法詳解
對(duì)于高并發(fā)系統(tǒng)來(lái)說(shuō),有三個(gè)重要的機(jī)制來(lái)保障其高效運(yùn)行,它們分別是:緩存、限流和熔斷,所以本文就來(lái)和大家探討一下多級(jí)緩存的實(shí)現(xiàn)方法,希望對(duì)大家有所幫助2024-02-02
Redis實(shí)現(xiàn)鎖續(xù)期的項(xiàng)目實(shí)踐
本文介紹了使用Redis實(shí)現(xiàn)分布式鎖的續(xù)期,包括使用Lua腳本、Redlock算法和Redisson客戶端等方法,具有一定的參考價(jià)值,感興趣的可以了解一下2024-12-12
Redis如何使用Pipeline實(shí)現(xiàn)批處理操作
Redis?Pipeline?是一種優(yōu)化?Redis?操作的機(jī)制,通過(guò)將多個(gè)命令打包發(fā)送到?Redis?服務(wù)器,減少客戶端與服務(wù)器之間的網(wǎng)絡(luò)往返時(shí)間,本文主要來(lái)聊聊Redis如何使用Pipeline實(shí)現(xiàn)批處理操作,需要的可以了解下2025-02-02
解決redis錯(cuò)誤消息:BUSYKEY Target key name alre
這篇文章主要介紹了解決redis錯(cuò)誤消息:BUSYKEY Target key name already exists.問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-04
redis分布式鎖之可重入鎖的實(shí)現(xiàn)代碼
相信大家都知道可重入鎖的作用防止在同一線程中多次獲取鎖而導(dǎo)致死鎖發(fā)生,本文通過(guò)幾個(gè)例子給大家分享redis分布式鎖之可重入鎖的實(shí)現(xiàn)代碼,對(duì)redis分布式鎖的相關(guān)知識(shí),感興趣的朋友一起看看吧2021-05-05
基于session?Redis實(shí)現(xiàn)登錄
這篇文章主要介紹了基于session?Redis實(shí)現(xiàn)登錄的相關(guān)資料,需要的朋友可以參考下2023-10-10

