Hi all, 來到第22天 有鑒於昨天將 redis 應用在專案上,突然有個發想,那就是假設這個專案在以後面臨到高流量的情況怎麼辦?
照目前的設計來說,我們確實可以在讀的方面減少對於 DB的呼叫,但在寫的這一塊卻是呼叫完DB再更新 Cache。基於這個因素,小弟有個想法,那就是 資料層直接對 Redis 做讀寫,意思就是每個 request 對於資料的讀寫都是直接對 Redis 進行呼叫,並在固定時間內將 Redis 上的資料放進 DB。
使用 Redis 快取每一個資料項目的設計可以大幅提升資料讀取的效能,特別是在高讀取場景下。然而,在實作這個策略時,需要考慮 Redis 的內存使用、鍵管理、一致性問題以及過期策略。根據你的業務需求,調整 Redis 的快取策略,將能夠充分利用 Redis 的優勢,同時避免潛在的問題。
這種設計思路(批量更新策略)在高流量和高併發場景下有著不錯的效能和可擴展性。它能夠顯著減少資料庫的負擔,提高系統的整體效能。然而,在實現這種架構時需要考慮資料一致性、錯誤恢復、內存管理和回寫策略等挑戰。
為了達到最佳效果,建議進行以下優化:
那這次的目標蠻明確了, 來列一下驗收條件
public class RedisTimeIntervalService(IConnectionMultiplexer connectionMultiplexer, IChainRepository chainRepository): IHostedService, IDisposable
{
private readonly IDatabase _redisService = connectionMultiplexer.GetDatabase();
private Timer? _timer;
public Task StartAsync(CancellationToken cancellationToken)
{
_timer = new Timer(PushRedisDataToDb, null, TimeSpan.Zero,
TimeSpan.FromSeconds(5));
return Task.CompletedTask;
}
private void PushRedisDataToDb(object? state)
{
var fromRedis = _redisService.StringGet("data");
if (fromRedis == "")
{
return ;
}
var blocks = JsonSerializer.Deserialize<List<Block>>(fromRedis);
chainRepository.SyncCacheToDb(blocks);
}
public Task StopAsync(CancellationToken cancellationToken)
{
_timer.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public void Dispose()
{
_timer.Dispose();
}
}
builder.Services.AddHostedService<RedisTimeIntervalService>();
public void SyncCacheToDb(List<Block> blocks)
{
foreach (var block in _blocks)
{
var firstOrDefault = blocks.FirstOrDefault(x=> x.Id == block.Id);
if (firstOrDefault != null)
{
block.Data = firstOrDefault.Data;
block.PreviousHash = firstOrDefault.PreviousHash;
block.Nonce = firstOrDefault.Nonce;
block.Hash = firstOrDefault.Hash;
block.TimeStamp = firstOrDefault.TimeStamp;
block.ChameleonSignature = firstOrDefault.ChameleonSignature;
continue;
}
_blocks.AddAsync(firstOrDefault!);
}
blockchainDbContext.SaveChangesAsync();
}
今天把專案原先透過 by request 透過 redis 再呼叫 db 轉變為批量寫進 db,另外再讓 request 取得資料的方式從db為主改為 redis為主。 但也不是說這樣個樣子是最好的,還是需要看使用場景,因此我這邊會開 branch來做個紀錄。
今天就先這樣,明天再來看看如果遇到併發時開怎麼做處理~~
結語: 昨晚不小喝太多~~~