编程知识 cdmana.com

Explication détaillée de l'instruction Scan avec redis

Utilisé dans l'environnement de productionkeysLes instructions peuvent facilement entraîner un blocage des demandes dans un court laps de temps,Cette condition est mortelle dans un environnement hautement simultané,Il est donc nécessaire d'éviter autant que possible que cela se produise.


Quelques requêtes couramment utiliséeskeyDirectives:

scan

jedisComment utiliser:

public List<String> scanAll(String cursor, String pattern, Integer limit) {
    
    try (Jedis jedis = iRedisFactory.getConnection()) {
    
        List<String> scanList = new LinkedList<>();
        ScanParams scanParams = new ScanParams();
        scanParams.match(pattern);
        scanParams.count(limit);
        while (true) {
    
            long begin = System.currentTimeMillis();
            ScanResult<String> scanResult = jedis.scan(cursor, scanParams);
            if (ScanParams.SCAN_POINTER_START.equals(scanResult.getCursor())) {
    
                break;
            }
            System.out.println("Ça prend du temps:" + (System.currentTimeMillis() - begin) + "ms, Nombre de requêtes :" + scanResult.getResult().size());
            scanList.addAll(scanResult.getResult());
            cursor = scanResult.getCursor();
        }
        return scanList;
    } catch (Exception e) {
    
        log.error("jedis scanAll has error, error is ", e);
    }
    return null;
}

Bien qu'il soit utilisé scan La complexité de la directive o(n) Il y aura un blocage partiel , Mais comme il s'agit de demandes multiples , C'est l'équivalent de keys La directive est divisée en plusieurs petites recherches , Réduire la durée du blocage .

sscan

jedisComment utiliser

public List<String> sScanAll(String key,String cursor, String pattern, Integer limit) {
    
    try(Jedis jedis = iRedisFactory.getConnection()) {
    
        List<String> resultList = new LinkedList<>();
        while (true) {
    
            ScanResult<String> scanResult = jedis.sscan(key,cursor);
            cursor = scanResult.getCursor();
            resultList.addAll(scanResult.getResult());
            if (ScanParams.SCAN_POINTER_START.equals(cursor)){
    
                break;
            }
        }
        return resultList;
    }catch (Exception e){
    
        log.error("jedis sscanAll has error, error is ", e);
    }
    return null;
}

En fait...sscan Les instructions combinent les noms pour deviner ,C'est unset Instructions de traversée utilisées par la collection , La comparaison est recommandée pour set Utilisation de la traversée dans la collection , Par exemple, quand notre set Quand il y a trop d'éléments de collection ,Utilisation directesmembers Les commandes sont susceptibles de causer des blocages ,Pour le momentsscan La directive peut réduire les cas de blocage .


hscan

jedisComment utiliser

public Map<String,String> hScanAll(String key, String cursor, String pattern, Integer limit) {
    
    try(Jedis jedis = iRedisFactory.getConnection()) {
    
        ScanParams scanParams = new ScanParams();
        scanParams.match(pattern);
        scanParams.count(limit);
        Map<String,String> resultList = new HashMap<>();
        while (true) {
    
            ScanResult scanResult = jedis.hscan(key,cursor,scanParams);
            cursor = scanResult.getCursor();
            if (ScanParams.SCAN_POINTER_START.equals(cursor)){
    
                break;
            }
            List<Map.Entry<String,String>> result = scanResult.getResult();
            for (Map.Entry<String, String> entry : result) {
    
                resultList.put(entry.getKey(),entry.getValue());
            }
        }
        return resultList;
    }catch (Exception e){
    
        log.error("jedis sscanAll has error, error is ", e);
    }
    return null;
}

C'est unhashmap Instructions de traversée utilisées par la collection

zscan

jedisComment utiliser

public List<String> zScanAll(String key, String cursor, String pattern, Integer limit) {
    
    try(Jedis jedis = iRedisFactory.getConnection()) {
    
        ScanParams scanParams = new ScanParams();
        scanParams.match(pattern);
        scanParams.count(limit);
        List<String> resultList = new LinkedList<>();
        while (true) {
    
            ScanResult scanResult = jedis.zscan(key,cursor,scanParams);
            cursor = scanResult.getCursor();
            if (ScanParams.SCAN_POINTER_START.equals(cursor)){
    
                break;
            }
            resultList.addAll(scanResult.getResult());
        }
        return resultList;
    }catch (Exception e){
    
        log.error("jedis sscanAll has error, error is ", e);
    }
    return null;
}

Il s'agit d'une instruction de traversée utilisée pour les collections ordonnées


InCentos Cas d'exécution de ces instructions sur le système d'exploitation :

scanDirectives

redis 127.0.0.1:6379> scan 0 MATCH *11*
1) "288"
2) 1) "key:911"
redis 127.0.0.1:6379> scan 288 MATCH *11*
1) "224"
2) (empty list or set)
redis 127.0.0.1:6379> scan 224 MATCH *11*
1) "80"
2) (empty list or set)
redis 127.0.0.1:6379> scan 80 MATCH *11*
1) "176"
2) (empty list or set)
redis 127.0.0.1:6379> scan 176 MATCH *11* COUNT 1000
1) "0"
2)  1) "key:611"
    2) "key:711"
    3) "key:118"
    4) "key:117"
    5) "key:311"
    6) "key:112"
    7) "key:111"
    8) "key:110"
    9) "key:113"
   10) "key:211"
   11) "key:411"
   12) "key:115"
   13) "key:116"
   14) "key:114"
   15) "key:119"
   16) "key:811"
   17) "key:511"
   18) "key:11"

sscanDirectives

> sscan vip-info-set 0 count 10
0
[[1001]]

zscanDirectives
> zscan review:222  0 match * count 10
0
idea
1
idea2
2
idea3
3
idea4
4

hscanDirectives

> hscan user-map  0 match *   count 10
0
1
user1
2
user2
3
user3

SCANOrdre de traversée de

À propos descanOrdre de traversée de la commande, On peut voir plus en détail .

> keys *
user
test-key-1
test-key-3
test-key-4
test-key-2
> scan 0 match * count 1
2
test-key-3
> scan 2 match * count 1
6
user
> scan 6 match * count 1
1
test-key-4
> scan 1 match * count 1
7
test-key-1
> scan 7 match * count 1
0
test-key-2

La nôtre.RedisOui.3- Oui.key,Nous ne traversons que les éléments d'un tableau unidimensionnel à la fois.Comme indiqué ci - dessus,SCANL'ordre de traversée de la commande est

0->2->6->1->7->0

Cet ordre semble étrange.C'est un peu compréhensible si on le convertit en binaire.Nous avons constaté que chaque fois que cette séquence est élevée plus1De.Addition au binaire ordinaire,C'est l'addition de droite à gauche、Carry.Et cette séquence est ajoutée de gauche à droite、Carrousel.

000->010->110->001->111->000

Alors pourquoi?redis L'auteur de ?

Cet endroit implique redisDerehashFonctionnement, Supposons que notre index original soit :

000->100->010->110->001->101->011->111

Après une série d'agrandissements , L'index devient :

0000->1000->0100->1100->0010->1010->0110->1110->0001->1001->1101->1111

Il s'est avéré qu'il était accroché àxxxTous les éléments ci - dessous sont assignés à0xxxEt1xxxEn bas..Quand on est sur le point de traverser010Heure,dictC'est fait.rehash,À ce moment - là,,scanLes commandes seront exécutées à partir de0100Commencez à traverser,Et000Et100(Original00Éléments suspendus en dessous)Il n'y aura plus de répétition.

Revenons à l'état du rétrécissement.HypothèsesdictDe4Bit zoom to3Bits,Quand vous êtes sur le point de traverser1110Heure,dictUn rétrécissement s'est produit,À ce moment - là,scanVa traverser011.À ce moment - là,011 Les éléments suivants sont itérés à plusieurs reprises ,Mais...011Aucun des éléments précédents n'est répété.Alors...,Il peut encore y avoir des éléments répétitifs à l'échelle.Par conséquent, il est utiliséscanAu moment de la commande, Des éléments répétitifs apparaissent parfois .

版权声明
本文为[Danny... Idea]所创,转载请带上原文链接,感谢
https://cdmana.com/2022/01/202201080559031435.html

Scroll to Top