Jedis運用scan刪除正則匹配的key


import redis.clients.jedis.Jedis;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;

import java.util.List;
import java.util.Set;

public class RedisApplication {

    private static String prefix = "ws:";
    static Jedis jedis;

    static {
        jedis = new Jedis("localhost");
        System.out.println("連接成功");
    }

    public static void main(String[] args) {
//       init();
        list();
//        scan();
        del();
    }

    private static void del() {
        Long count = jedis.del("abc");
        System.out.println(count);
    }
    private static void scan() {
        ScanParams params = new ScanParams();
        params.match("ws:*");
//        params.count(3);
        String cursor = "0";
        while (true) {
            ScanResult<String> scanResult = jedis.scan(cursor, params);
            List<String> elements = scanResult.getResult();
            if (elements != null && elements.size() > 0) {
                System.out.println(elements);
            }
            cursor = scanResult.getStringCursor();
            if ("0".equals(cursor)) {
                break;
            }
        }
    }

    private static void list() {
        Set<String> keys = jedis.keys("ws:*");
        for (String key : keys) {
            System.out.println(key);
        }
        System.out.println("====");
    }

    private static void init() {
        for (int i = 0; i < 5; i++) {
            jedis.set(prefix + i, i + "");
        }
    }
}

keys爲何不能在生產使用?

redis的keys命令,通來在用來刪除相關的key時使用,但這個命令有一個弊端,在redis擁有數百萬及以上的keys的時候,會執行的比較慢,更爲致命的是,這個命令會阻塞redis多路複用的io主線程,如果這個線程阻塞,在此執行之間其他的發送向redis服務端的命令,都會阻塞,從而引發一系列級聯反應,導致瞬間響應卡頓,從而引發超時等問題,所以應該在生產環境禁止用使用keys和類似的命令smembers,這種時間複雜度爲O(N),且會阻塞主線程的命令,是非常危險的。

scan的優點

那麼在生產環境我們應該使用scan命令,代替keys命令,同樣是O(N)複雜度的scan命令,支持通配查找,scan命令或者其他的scan如SSCAN ,HSCAN,ZSCAN命令,可以不用阻塞主線程,並支持遊標按批次迭代返回數據,所以是比較理想的選擇。keys相比scan命令優點是,keys是一次返回,而scan是需要迭代多次返回。 但scan命令的也有缺點,返回的數據有可能重複

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章