欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Redis高并發(fā)緩存設(shè)計問題與性能優(yōu)化

 更新時間:2024年11月11日 11:37:00   作者:鐘林@  
本文詳細介紹了Redis緩存設(shè)計中常見的問題及解決方案,包括緩存穿透、緩存失效(擊穿)、緩存雪崩、熱點緩存key重建優(yōu)化、緩存與數(shù)據(jù)庫雙寫不一致以及開發(fā)規(guī)范與性能優(yōu)化,感興趣的可以了解一下

1、緩存設(shè)計典型問題

1.1、緩存穿透

緩存穿透是指查詢一個根本不存在的數(shù)據(jù),緩存層和存儲層都不會命中,通常出于容錯的考慮,如果從存儲層查不到數(shù)據(jù)則不寫入緩存層。

緩存穿透將導(dǎo)致不存在的數(shù)據(jù)每次請求都要到存儲層去查詢,失去了緩存保護后端存儲的意義。造成緩存穿透的基本原因有兩個:

第一,自身業(yè)務(wù)代碼或者數(shù)據(jù)出現(xiàn)問題。

第二,一些惡意攻擊、爬蟲等造成大量空命中。

緩存穿透問題解決方案:

    public String get (String key){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(20);
        jedisPoolConfig.setMaxIdle(10);
        jedisPoolConfig.setMaxWaitMillis(5);
        //timeout,這里既是連接超時又是讀寫超時,從Jedis2.8 開始有區(qū)分 connectionTimeout 和soTimeout 的構(gòu)造函數(shù)

        JedisPool jedisPool = new JedisPool(jedisPoolConfig, "127.0.0.1", 6379, 3000, "redis");

        Jedis cache =jedisPool.getResource();
        // 從緩存中獲取數(shù)據(jù)
        String cacheValue = cache.get(key);
        // 緩存為空,從數(shù)據(jù)庫中獲取數(shù)據(jù)
        if (StrUtil.isEmpty(cacheValue)){
            // 從數(shù)據(jù)庫中獲取數(shù)據(jù)
            String storageValue = "data from db";
            cache.set(key, storageValue);
            // 如果存儲數(shù)據(jù)為空,需要設(shè)置一個過去時間(300秒)
            if (StrUtil.isEmpty(storageValue)){
                cache.expire(key,60 * 5);
            }
            return cacheValue;
        }else {
            // 緩存不為空,直接返回
            return cacheValue;
        }
    }

1.2、布隆過濾器

對于惡意攻擊,向服務(wù)器請求大量不存在的數(shù)據(jù)造成的緩存穿透,還可以用布隆過濾器先做一次過濾,對于不存在的數(shù)據(jù)布隆過濾器一般都能夠過濾掉,不讓請求再往后端發(fā)送。當布隆過濾器說某個值存在時,這個值可能不存在;當它說不存在時,那就肯定不存在。

 布隆過濾器就是一個大型的位數(shù)組和幾個不一樣的無偏hash函數(shù)。所謂無偏就是能夠把元素的hash值算得比較均勻。

向布隆過濾器中添加key時,會使用多個hash函數(shù)對key進行hash算得一個整數(shù)索引值然后對位數(shù)組長度進行取模運算得到一個位置,每個hash函數(shù)都會算得一個不同的位置。再把位數(shù)組的這幾個位置都置為1就完成了add操作。

向布隆過濾器詢問key是否存在時,跟add一樣,也會把hash的幾個位置都算出來,看看位數(shù)組中這幾個位置是否都為1,只要有一個位為0,那么說明布隆過濾器中這個key不存在。如果都是1,這并不能說明這個key就一定存在,只是極有可能存在,因為這些位被置為1可能是因為其它的key存在所致。如果這個位數(shù)組比較稀疏,這個概率就會很大,如果這個位數(shù)組比較擁擠,這個概率就會降低。

這種方法適用于數(shù)據(jù)命中不高、數(shù)據(jù)相對固定、實時性低(通常是數(shù)據(jù)集較大)的應(yīng)用場景,代碼維護較為復(fù)雜,但是緩存空間占用很少

可以用redisson實現(xiàn)布隆過濾器,引入依賴:

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.6.5</version>
</dependency>

示例偽代碼:

import org.redisson.Redisson;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;

/**
 * @Author hw
 * @Date 2024/10/8 10:55
 * @PackageName:com.redxun.eip.controller.jobController
 * @ClassName: RedissonBloomFilter
 * @Description: redisson實現(xiàn)布隆過濾器
 * @Version 1.0
 */
public class RedissonBloomFilter {
    public static void main(String[] args) {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        // 構(gòu)造Redisson
        RedissonClient redisson = Redisson.create(config);

        RBloomFilter<String> bloomFilter = redisson.getBloomFilter("nameList");
        //初始化布隆過濾器:預(yù)計元素為100000000L,誤差率為3%,根據(jù)這兩個參數(shù)會計算出底層bit數(shù)組大小
        bloomFilter.tryInit(100000000L, 0.03);
        // 將zhuge插入布隆過濾器中
        bloomFilter.add("zhuge");
        
        // 判斷下面號碼是否存在于布隆過濾器中
        System.out.println(bloomFilter.contains("guojia"));// false
        System.out.println(bloomFilter.contains("baiqi")); // false
        System.out.println(bloomFilter.contains("zhuge")); // true
    }
}

使用布隆過濾器需要把所有數(shù)據(jù)提前放入布隆過濾器,并且在增加數(shù)據(jù)時也要往布隆過濾器里放,布隆過濾器緩存過濾偽代碼:

import cn.hutool.core.util.StrUtil;
import org.redisson.Redisson;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author hw
 * @Date 2024/10/8 10:55
 * @PackageName:com.redxun.eip.controller.jobController
 * @ClassName: RedissonBloomFilter
 * @Description: redisson實現(xiàn)布隆過濾器
 * @Version 1.0
 */
public class RedissonBloomFilter {
    public static void main(String[] args) {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        // 構(gòu)造Redisson
        RedissonClient redisson = Redisson.create(config);

        RBloomFilter<String> bloomFilter = redisson.getBloomFilter("nameList");
        //初始化布隆過濾器:預(yù)計元素為100000000L,誤差率為3%,根據(jù)這兩個參數(shù)會計算出底層bit數(shù)組大小
        bloomFilter.tryInit(100000000L, 0.03);
        // 將zhuge插入布隆過濾器中
        bloomFilter.add("zhuge");

        // 判斷下面號碼是否存在于布隆過濾器中
        System.out.println(bloomFilter.contains("guojia"));// false
        System.out.println(bloomFilter.contains("baiqi")); // false
        System.out.println(bloomFilter.contains("zhuge")); // true
    }

    /**
     * 添加所有key數(shù)據(jù)到布隆過濾器中
     */
    public void pushBloomFilter() {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        // 構(gòu)造Redisson
        RedissonClient redisson = Redisson.create(config);

        RBloomFilter<String> bloomFilter = redisson.getBloomFilter("nameList");
        //初始化布隆過濾器:預(yù)計元素為100000000L,誤差率為3%,根據(jù)這兩個參數(shù)會計算出底層bit數(shù)組大小
        bloomFilter.tryInit(100000000L, 0.03);

        List<String> keys = new ArrayList<>();
        keys.add("zhuge");
        keys.add("guojia");
        keys.add("baiqi");
        // 把所有數(shù)據(jù)存入布隆過濾器
        for (String key: keys) {
            bloomFilter.add(key);
        }
    }

    /**
     * 從布隆過濾器中過濾并獲取數(shù)據(jù)
     * @param key
     * @return
     */
    public String get (String key){
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        // 構(gòu)造Redisson
        RedissonClient redisson = Redisson.create(config);

        RBloomFilter<String> bloomFilter = redisson.getBloomFilter("nameList");

        // 從布隆過濾器這一級緩存判斷下key是否存在
        boolean exists = bloomFilter.contains(key);
        if (!exists){
            return "";
        }


        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(20);
        jedisPoolConfig.setMaxIdle(10);
        jedisPoolConfig.setMaxWaitMillis(5);
        //timeout,這里既是連接超時又是讀寫超時,從Jedis2.8 開始有區(qū)分 connectionTimeout 和soTimeout 的構(gòu)造函數(shù)

        JedisPool jedisPool = new JedisPool(jedisPoolConfig, "127.0.0.1", 6379, 3000, "redis");

        Jedis cache =jedisPool.getResource();
        // 從緩存中獲取數(shù)據(jù)
        String cacheValue = cache.get(key);
        // 緩存為空,從數(shù)據(jù)庫中獲取數(shù)據(jù)
        if (StrUtil.isEmpty(cacheValue)){
            // 從數(shù)據(jù)庫中獲取數(shù)據(jù)
            String storageValue = "data from db";
            cache.set(key, storageValue);
            // 如果存儲數(shù)據(jù)為空,需要設(shè)置一個過去時間(300秒)
            if (StrUtil.isEmpty(storageValue)){
                cache.expire(key,60 * 5);
            }
            return cacheValue;
        }else {
            // 緩存不為空,直接返回
            return cacheValue;
        }
    }
}

注意:布隆過濾器不能刪除數(shù)據(jù),如果要刪除得重新初始化數(shù)據(jù)。

1.3、緩存失效(擊穿)

由于大批量緩存在同一時間失效可能導(dǎo)致大量請求同時穿透緩存直達數(shù)據(jù)庫,可能會造成數(shù)據(jù)庫瞬間壓力過大甚至掛掉,對于這種情況我們在批量增加緩存時最好將這一批數(shù)據(jù)的緩存過期時間設(shè)置為一個時間段內(nèi)的不同時間。

示例偽代碼:

    public String get (String key){
        // 連接redis
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(20);
        jedisPoolConfig.setMaxIdle(10);
        jedisPoolConfig.setMaxWaitMillis(5);
        //timeout,這里既是連接超時又是讀寫超時,從Jedis2.8 開始有區(qū)分 connectionTimeout 和soTimeout 的構(gòu)造函數(shù)

        JedisPool jedisPool = new JedisPool(jedisPoolConfig, "127.0.0.1", 6379, 3000, "redis");

        Jedis cache =jedisPool.getResource();
        // 從緩存中獲取數(shù)據(jù)
        String cacheValue = cache.get(key);
        // 緩存為空,從數(shù)據(jù)庫中獲取數(shù)據(jù)
        if (StrUtil.isEmpty(cacheValue)){
            // 從數(shù)據(jù)庫中獲取數(shù)據(jù)
            String storageValue = "data from db";
            cache.set(key, storageValue);
            // 設(shè)置一個過期時間(300到600之間的一個隨機數(shù))
            int expireTime = new Random().nextInt(300) + 300;
            if (StrUtil.isEmpty(storageValue)){
                cache.expire(key,expireTime);
            }
            return cacheValue;
        }else {
            // 緩存不為空,直接返回
            return cacheValue;
        }
    }

1.4、緩存雪崩

緩存雪崩指的是緩存層支撐不住或宕掉后,流量會像奔逃的野牛一樣,打向后端存儲層。

由于緩存層承載著大量請求,有效地保護了存儲層,但是如果緩存層由于某些原因不能提供服務(wù)(比如超大并發(fā)過來,緩存層支撐不住,或者由于緩存設(shè)計不好,類似大量請求訪問bigkey,導(dǎo)致緩存能支撐的并發(fā)急劇下降),于是大量請求都會打到存儲層,存儲層的調(diào)用量會暴增,造成存儲層也會級聯(lián)宕機的情況。

預(yù)防和解決緩存雪崩問題,可以從以下三個方面進行著手。

1)保證緩存層服務(wù)高可用性,比如使用 RedisSentinel 或 RedisCluster。

2)依賴隔離組件為后端限流熔斷并降級。比如使用 Sentinel 或 Hystrix 限流降級組件。

比如服務(wù)降級,我們可以針對不同的數(shù)據(jù)采取不同的處理方式。當業(yè)務(wù)應(yīng)用訪問的是非核心數(shù)據(jù)(例如電商商品屬性,用戶信息等)時,暫時停止從緩存中查詢這些數(shù)據(jù),而是直接返回預(yù)定義的默認降級信息、空值或是錯誤提示信息;當業(yè)務(wù)應(yīng)用訪問的是核心數(shù)據(jù)(例如電商商品庫存)時,仍然允許查詢緩存,如果緩存缺失,也可以繼續(xù)通過數(shù)據(jù)庫讀取。 

3)提前演練。在項目上線前,演練緩存層宕掉后,應(yīng)用以及后端的負載情況以及可能出現(xiàn)的問題,在此基礎(chǔ)上做一些預(yù)案設(shè)定。

1.5、熱點緩存key重建優(yōu)化

開發(fā)人員使用“緩存+過期時間”的策略既可以加速數(shù)據(jù)讀寫,又保證數(shù)據(jù)的定期更新,這種模式基本能夠滿足絕大部分需求。但是有兩個問題如果同時出現(xiàn),可能就會對應(yīng)用造成致命的危害:

  • 當前key是一個熱點key(例如一個熱門的娛樂新聞),并發(fā)量非常大。
  • 重建緩存不能在短時間完成,可能是一個復(fù)雜計算,例如復(fù)雜的SQL、多次IO、多個依賴等。

在緩存失效的瞬間,有大量線程來重建緩存,造成后端負載加大,甚至可能會讓應(yīng)用崩潰。

要解決這個問題主要就是要避免大量線程同時重建緩存。

我們可以利用互斥鎖來解決,此方法只允許一個線程重建緩存,其他線程等待重建緩存的線程執(zhí)行完,重新從緩存獲取數(shù)據(jù)即可。

示例偽代碼:

public String get (String key) throws InterruptedException {
        // 連接redis
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(20);
        jedisPoolConfig.setMaxIdle(10);
        jedisPoolConfig.setMaxWaitMillis(5);
        //timeout,這里既是連接超時又是讀寫超時,從Jedis2.8 開始有區(qū)分 connectionTimeout 和soTimeout 的構(gòu)造函數(shù)

        JedisPool jedisPool = new JedisPool(jedisPoolConfig, "127.0.0.1", 6379, 3000, "redis");

        Jedis cache = jedisPool.getResource();
        // 從緩存中獲取數(shù)據(jù)
        String value = cache.get(key);
        // 緩存為空,從數(shù)據(jù)庫中獲取數(shù)據(jù)
        if (StrUtil.isEmpty(value)){
            // 只允許一個線程重建緩存,使用 nx, 并設(shè)置過期時間 ex
            String mutexKey = "mutex:key:" + key;
            if (cache.set(mutexKey, "1","ex 180","nx")) {
                // 從數(shù)據(jù)庫中獲取數(shù)據(jù)
                value = "dbValue";
                // 回寫Redis, 并設(shè)置過期時間
                cache.set(key, value);
                cache.expire(key, 60*5);
                // 刪除 key_mutex
                cache.del(mutexKey);
            }else {
                //其他線程等待 50 毫秒后重試
                Thread.sleep(50);
                get(key);
            }
        }
        return value;
    }

1.6、緩存與數(shù)據(jù)庫雙寫不一致

在大并發(fā)下,同時操作數(shù)據(jù)庫與緩存會存在數(shù)據(jù)不一致性問題

1.6.1、雙寫不一致情況

 1.6.2、讀寫并發(fā)不一致

 解決方案:

1、對于并發(fā)幾率很小的數(shù)據(jù)(如個人維度的訂單數(shù)據(jù)、用戶數(shù)據(jù)等),這種幾乎不用考慮這個問題,很少會發(fā)生緩存不一致,可以給緩存數(shù)據(jù)加上過期時間,每隔一段時間觸發(fā)讀的主動更新即可。

2、就算并發(fā)很高,如果業(yè)務(wù)上能容忍短時間的緩存數(shù)據(jù)不一致(如商品名稱,商品分類菜單等),緩存加上過期時間依然可以解決大部分業(yè)務(wù)對于緩存的要求。

3、如果不能容忍緩存數(shù)據(jù)不一致,可以通過加讀寫鎖保證并發(fā)讀寫或?qū)憣懙臅r候按順序排好隊,讀讀的時候相當于無鎖。

4、也可以用阿里開源的canal通過監(jiān)聽數(shù)據(jù)庫的binlog日志及時的去修改緩存,但是引入了新的中間件,增加了系統(tǒng)的復(fù)雜度。

 總結(jié):

以上我們針對的都是讀多寫少的情況加入緩存提高性能,如果寫多讀多的情況又不能容忍緩存數(shù)據(jù)不一致,那就沒必要加緩存了,可以直接操作數(shù)據(jù)庫。當然,如果數(shù)據(jù)庫抗不住壓力,還可以把緩存作為數(shù)據(jù)讀寫的主存儲,異步將數(shù)據(jù)同步到數(shù)據(jù)庫,數(shù)據(jù)庫只是作為數(shù)據(jù)的備份。

放入緩存的數(shù)據(jù)應(yīng)該是對實時性、一致性要求不是很高的數(shù)據(jù)。切記不要為了用緩存,同時又要保證絕對的一致性做大量的過度設(shè)計和控制,增加系統(tǒng)復(fù)雜性!

 1.7、開發(fā)規(guī)范與性能優(yōu)化

 1.7.1、鍵值設(shè)計

1.key名設(shè)計

(1)【建議】:可讀性和可管理性

以業(yè)務(wù)名(或數(shù)據(jù)庫名)為前綴(防止key沖突),用冒號分隔,比如業(yè)務(wù)名:表名:id

rade:order:1

(2)【建議】:簡潔性

保證語義的前提下,控制key的長度,當key較多時,內(nèi)存占用也不容忽視,例如:

user:{uid}:friends:messages:{mid}簡化為u:{uid}:fr:m:{mid}

(3)【強制】:不要包含特殊字符

反例:包含空格、換行、單雙引號以及其他轉(zhuǎn)義字符

2.value設(shè)計

(1)【強制】:拒絕 bigkey (防止網(wǎng)卡流量、慢查詢)

在Redis中,一個字符串最大512MB,一個二級數(shù)據(jù)結(jié)構(gòu)(例如hash、list、set、zset)可以存儲大約40億個(2^32-1)個元素,但實際中如果下面兩種情況,我就會認為它是bigkey。

1.字符串類型:它的big體現(xiàn)在單個value值很大,一般認為超過10KB就是bigkey。

2.非字符串類型:哈希、列表、集合、有序集合,它們的big體現(xiàn)在元素個數(shù)太多。

一般來說,string類型控制在10KB以內(nèi),hash、list、set、zset元素個數(shù)不要超過5000。

反例:一個包含200萬個元素的list。

非字符串的bigkey,不要使用del刪除,使用hscan、sscan、zscan方式漸進式刪除,同時要注意防止bigkey過期時間自動刪除問題(例如一個200萬的zset設(shè)置1小時過期,會觸發(fā)del操作,造成阻塞)

bigkey的危害:

1.導(dǎo)致redis阻塞

2.網(wǎng)絡(luò)擁塞

bigkey也就意味著每次獲取要產(chǎn)生的網(wǎng)絡(luò)流量較大,假設(shè)一個bigkey為1MB,客戶端每秒訪問量為1000,那么每秒產(chǎn)生1000MB的流量,對于普通的千兆網(wǎng)卡(按照字節(jié)算是128MB/s)的服務(wù)器來說簡直是滅頂之災(zāi),而且一般服務(wù)器會采用單機多實例的方式來部署,也就是說一個bigkey可能會對其他實例也造成影響,其后果不堪設(shè)想。

3.過期刪除

有個bigkey,它安分守己(只執(zhí)行簡單的命令,例如hget、lpop、zscore等),但它設(shè)置了過期時間,當它過期后,會被刪除,如果沒有使用Redis4.0的過期異步刪除(lazyfree-lazyexpireyes),就會存在阻塞Redis的可能性。

bigkey的產(chǎn)生:

一般來說,bigkey的產(chǎn)生都是由于程序設(shè)計不當,或者對于數(shù)據(jù)規(guī)模預(yù)料不清楚造成的,來看幾個例子:

(1)社交類:粉絲列表,如果某些明星或者大v不精心設(shè)計下,必是bigkey。

(2)統(tǒng)計類:例如按天存儲某項功能或者網(wǎng)站的用戶集合,除非沒幾個人用,否則必是bigkey。

(3)緩存類:將數(shù)據(jù)從數(shù)據(jù)庫load出來序列化放到Redis里,這個方式非常常用,但有兩個地方需要注意,第一,是不是有必要把所有字段都緩存;第二,有沒有相關(guān)關(guān)聯(lián)的數(shù)據(jù),有的同學(xué)為了圖方便把相關(guān)數(shù)據(jù)都存一個key下,產(chǎn)生bigkey。

如何優(yōu)化bigkey

1.拆

biglist:list1、list2、...listN

bighash:可以講數(shù)據(jù)分段存儲,比如一個大的key,假設(shè)存了1百萬的用戶數(shù)據(jù),可以拆分成200個key,每個key下面存放5000個用戶數(shù)據(jù)

2.如果bigkey不可避免,也要思考一下要不要每次把所有元素都取出來(例如有時候僅僅需要hmget,而不是hgetall),刪除也是一樣,盡量使用優(yōu)雅的方式來處理。

(2)【推薦】:選擇適合的數(shù)據(jù)類型。

例如:實體類型(要合理控制和使用數(shù)據(jù)結(jié)構(gòu),但也要注意節(jié)省內(nèi)存和性能之間的平衡)

反例:

set user:1:name tom
set user:1:age 19
set user:1:favor football

正例:

hmset user:1 name tom age 19 favor football

3.【推薦】:控制key的生命周期,redis不是垃圾桶。

建議使用expire設(shè)置過期時間(條件允許可以打散過期時間,防止集中過期)。

 1.7.2、命令使用

1.【推薦】O(N)命令關(guān)注N的數(shù)量

例如hgetall、lrange、smembers、zrange、sinter等并非不能使用,但是需要明確N的值。有遍歷的需求可以使用hscan、sscan、zscan代替。

2.【推薦】:禁用命令

禁止線上使用keys、flushall、flushdb等,通過redis的rename機制禁掉命令,或者使用scan的方式漸進式處理。

3.【推薦】合理使用select

redis的多數(shù)據(jù)庫較弱,使用數(shù)字進行區(qū)分,很多客戶端支持較差,同時多業(yè)務(wù)用多數(shù)據(jù)庫實際還是單線程處理,會有干擾。

4.【推薦】使用批量操作提高效率

原生命令:例如mget、mset。

非原生命令:可以使用pipeline提高效率。

但要注意控制一次批量操作的元素個數(shù)(例如500以內(nèi),實際也和元素字節(jié)數(shù)有關(guān))。注意兩者不同:

1.原生命令是原子操作,pipeline 是非原子操作。

2.pipeline 可以打包不同的命令,原生命令做不到

3.pipeline 需要客戶端和服務(wù)端同時支持。

5.【建議】Redis事務(wù)功能較弱,不建議過多使用,可以用lua替代

到此這篇關(guān)于Redis高并發(fā)緩存設(shè)計問題與性能優(yōu)化的文章就介紹到這了,更多相關(guān)Redis高并發(fā)緩存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis操作命令總結(jié)

    Redis操作命令總結(jié)

    這篇文章主要介紹了Redis操作命令總結(jié),本文講解了key pattern 查詢相應(yīng)的key、字符串類型的操作、鏈表操作、hashes類型及操作、集合結(jié)構(gòu)操作、有序集合、服務(wù)器相關(guān)命令等內(nèi)容,需要的朋友可以參考下
    2015-03-03
  • Deepin UOS編譯安裝Redis的實現(xiàn)步驟

    Deepin UOS編譯安裝Redis的實現(xiàn)步驟

    本文主要介紹了Deepin UOS編譯安裝Redis的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • 基于Redis實現(xiàn)基本搶紅包算法詳解

    基于Redis實現(xiàn)基本搶紅包算法詳解

    [key, value]的緩存數(shù)據(jù)庫, Redis官方性能描述非常高, 所以面對高并發(fā)場景, 使用Redis來克服高并發(fā)壓力是一個不錯的手段, 本文主要基于Redis來實現(xiàn)基本的搶紅包系統(tǒng)設(shè)計,感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • 詳解Redis SCAN命令實現(xiàn)有限保證的原理

    詳解Redis SCAN命令實現(xiàn)有限保證的原理

    這篇文章主要介紹了Redis SCAN命令實現(xiàn)有限保證的原理,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值 ,需要的朋友可以參考下
    2019-07-07
  • redis查詢keys報錯的實現(xiàn)

    redis查詢keys報錯的實現(xiàn)

    在Redis中使用KEYS命令來查詢所有符合特定模式的鍵名是一個常見需求,本文主要介紹了redis查詢keys報錯的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2025-04-04
  • Mac中Redis服務(wù)啟動時錯誤信息:NOAUTH Authentication required

    Mac中Redis服務(wù)啟動時錯誤信息:NOAUTH Authentication required

    這篇文章主要介紹了Mac中使用Redis服務(wù)啟動時錯誤信息:"NOAUTH Authentication required"問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Redis中LRU算法和LFU算法的區(qū)別小結(jié)

    Redis中LRU算法和LFU算法的區(qū)別小結(jié)

    在Redis中,LRU算法和LFU算法是兩種常用的緩存淘汰算法,它們可以幫助我們優(yōu)化緩存性能,本文主要介紹了Redis中LRU算法和LFU算法的區(qū)別,感興趣的可以了解一下
    2023-12-12
  • redis實現(xiàn)動態(tài)字符串SDS

    redis實現(xiàn)動態(tài)字符串SDS

    簡單動態(tài)字符串是Redis的基本數(shù)據(jù)結(jié)構(gòu)之一,用于存儲字符串和整型數(shù)據(jù),本文主要介紹了redis實現(xiàn)動態(tài)字符串SDS,具有一定的參考價值,感興趣的可以了解一下
    2024-04-04
  • Redis源碼閱讀:Redis字符串SDS詳解

    Redis源碼閱讀:Redis字符串SDS詳解

    這篇文章主要介紹了Redis源碼閱讀:Redis字符串SDS,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Redis面試必備之緩存設(shè)計規(guī)范與性能優(yōu)化詳解

    Redis面試必備之緩存設(shè)計規(guī)范與性能優(yōu)化詳解

    你是否在使用Redis時,不清楚Redis應(yīng)該遵循的設(shè)計規(guī)范而苦惱,你是否在Redis出現(xiàn)性能問題時,不知道該如何優(yōu)化而發(fā)愁,快跟隨小編一起學(xué)習(xí)起來吧
    2024-03-03

最新評論