Redis de l'entrée au combat réel


Préface

Aujourd'hui, mon père a payé quelques centaines de yuans de plus pour les frais de subsistance, alors il a acheté un nouveau nœud de serveur cloud (la réduction étudiante ne peut prendre en charge qu'un seul serveur, et c'est beaucoup plus cher sans la réduction, donc la configuration d'origine uniquement Acheté pendant deux semaines), le nouveau nœud est principalement utilisé pour la réplication maître-esclave redis et l'équilibrage de la charge du cluster. Contexte du projet: Il s'agit actuellement d'une plate-forme de commerce électronique avec une architecture unique, comprenant des utilisateurs, des commandes, des paniers d'achat, des recherches, des avis, etc. La base de données utilise MySQL. Le projet a été déployé sur le serveur cloud et a fait l'objet d'un proxy inverse avec nginx. Le mouvement est séparé. Objectif: utiliser redis pour optimiser la partie panier (attention particulière à la logique de cache des cookies et redis), construire la réplication maître-esclave, optimiser l'architecture redis, améliorer la fiabilité de redis, résoudre la pénétration du cache et éviter les avalanches de cache.

1. Pourquoi utiliser redis

  • Avantages de Redis
    • haute vitesse. Redis est entièrement basé sur la mémoire et implémenté en langage C. La couche réseau utilise epoll pour résoudre les problèmes de concurrence élevée. Le modèle monothread évite les changements de contexte et les conditions de concurrence inutiles.
    • Structure de données riche. Y compris la chaîne, le hachage, l'ensemble, la liste, etc.
    • Prise en charge de la persistance, de la synchronisation maître-esclave, du basculement et d'autres fonctions
  • Inconvénients de Redis
    • Fil unique
    • Noyau unique
  • Comparaison de Memcache et redis
    • Memcache ne prend pas en charge la persistance
    • Memcache multi-core multi-thread
    • Memcache a moins de structure de données

Résumé : Redis convient au stockage de données chaudes (grand volume d'accès), prend en charge le stockage persistant et fournit des fonctions riches.

Deux, modèle de multiplexage

Comme mentionné précédemment, redis est monothread et monocœur. Imaginez la situation suivante: si plusieurs tâches d'E / S doivent être effectuées par redis, pour redis, s'il a été bloqué en attente d'E / S, cela entraînera une inefficacité.
Redis adopte un modèle de multiplexage. Lorsqu'une requête arrive, s'il veut attendre, le multiplexeur traitera d'autres requêtes; lors du traitement de la requête, le multiplexeur n'implémente pas vraiment la logique de traitement, mais la tâche Jetez-le au processeur derrière.
D'une part, le fil unique évite la commutation et le verrouillage du processeur, d'autre part, le multiplexage évite la perte d'efficacité de l'attente de blocage. Cela garantit la vitesse de redis.

Trois, opération de base Redis

1. chaîne

2. hachage

3. liste

4. ensemble


Quatrièmement, l'intégration du module de panier d'achat Redis Optimisation dans le projet

1. Entreprise d'origine

Les données du panier d'origine ne sont pas mises à jour dans la base de données, mais un cookie est mis en cache par le navigateur. Lorsque l'utilisateur n'est pas connecté, il peut soumettre le produit au panier, mais il ne peut pas passer une commande. Une fois que l'utilisateur s'est connecté, il peut passer une commande et mettre à jour la commande dans la base de données.

2. Tâche cible

Utilisez redis pour stocker de manière permanente les données dans le panier et pouvoir intégrer les cookies

3. Logique de mise en œuvre

1.redis中无数据
	如果cookie中的购物车为空,那么这个时候不做处理
    如果cookie中的购物车不为空,直接覆盖redis
2.redis中有数据
	如果cookie中的购物车为空,那么直接把redis的购物车覆盖本地cookie中
    如果cookie中的购物车不为空,redis中也存在,则以cookie为准,覆盖redis
3.同步到redis中之后,覆盖本地cookie购物车的数据,保证本地购物车的数据是同步的
	/*
     * 注册登录成功后,同步cookie和redis中的购物车数据
     * */
    private void sychShopcartData(String userId, HttpServletRequest request,
                                  HttpServletResponse response) {
    
    
        //1 从redis中获取购物车
        String shopcartJsonRedis = redisOperator.get(FOODIE_SHOPCART + ":" + userId);

        //2 从cookie中获取购物车
        String shopcartStrCookie = CookieUtils.getCookieValue(request, FOODIE_SHOPCART, true);

        if (StringUtils.isBlank(shopcartJsonRedis)) {
    
    
            //redis为空,cookie不为空,把cookie放进redis
            if (StringUtils.isNotBlank(shopcartStrCookie)) {
    
    
                redisOperator.set(FOODIE_SHOPCART + ":" + userId, shopcartStrCookie);
            }
        } else {
    
    
            //redis不为空,cookie不为空,合并cookie和redis中购物车的商品数据(同一商品覆盖redis)
            if (StringUtils.isNotBlank(shopcartStrCookie)) {
    
    
                /*
                 * 1.已经存在的,把cookie中对应的数量,覆盖redis
                 * 2.该项商品标记为待删除,统一放入一个待删除的list
                 * 3.从cookie 中清理所有的待删除list
                 * 4.合并redis和cookie中的数据
                 * 5.更新到redis和cookie中
                 * */
                List<ShopcartBO> shopcartBOListRedis = JsonUtils.jsonToList(shopcartJsonRedis, ShopcartBO.class);
                List<ShopcartBO> shopcartBOListCookie = JsonUtils.jsonToList(shopcartStrCookie, ShopcartBO.class);

                //定义待删除List
                List<ShopcartBO> pendingDeleyeList = new ArrayList<>();

                for (ShopcartBO redisShopcart : shopcartBOListRedis) {
    
    
                    String redisSpecId = redisShopcart.getSpecId();
                    for (ShopcartBO cookieShopcart : shopcartBOListCookie) {
    
    
                        String cookieSpecId = redisShopcart.getSpecId();
                        if (redisSpecId.equals(cookieSpecId)) {
    
    
                            //覆盖购买数量,不累加
                            redisShopcart.setBuyCounts(cookieShopcart.getBuyCounts());
                            //把cookieShopcart放入待删除列表,用于最后的删除合并
                            pendingDeleyeList.add(cookieShopcart);
                        }
                    }
                }
                //从现有cookie中删除对应的覆盖过的商品数据
                shopcartBOListCookie.removeAll(pendingDeleyeList);
                //合并两个list
                shopcartBOListRedis.addAll(shopcartBOListCookie);
                //更新到cookie和redis
                CookieUtils.setCookie(request, response, FOODIE_SHOPCART, JsonUtils.objectToJson(shopcartBOListRedis), true);
                redisOperator.set(FOODIE_SHOPCART + ":" + userId, JsonUtils.objectToJson(shopcartBOListRedis));

            } else {
    
    
                //redis不为空,cookie为空,直接把redis覆盖cookie
                CookieUtils.setCookie(request, response, FOODIE_SHOPCART, shopcartJsonRedis, true);
            }
        }

    }

Cinq, publiez et abonnez-vous

Six, persistance Redis

Après avoir lu la théorie précédente, certaines personnes peuvent se sentir confuses: Redis est entièrement basé sur la mémoire, mais peut-il être persistant? ? Lorsque l'alimentation est coupée, les données de la mémoire ont disparu? ?
Référence: document officiel Redis

Redis fournit deux solutions de persistance: RDB (Redis Database), AOF (Append Only File)

RDB

À intervalles réguliers, les données de la mémoire sont écrites dans un fichier temporaire sur le disque en tant que cliché et le fichier de cliché est lu dans la mémoire lors de la restauration. Si la machine est redémarrée et que les données de la mémoire sont perdues, après le redémarrage de Redis, elles seront restaurées

  • avantage:
    1. Sauvegarde de temps en temps, sauvegarde complète
    2. Reprise après sinistre simple, transmission à distance
    3. Lorsque le processus enfant est sauvegardé, le processus principal n'aura aucune opération d'E / S (lisible) pour garantir l'intégrité des données de sauvegarde
    4. Comparé à AOF, il peut être redémarré et restauré rapidement lorsqu'il y a des fichiers plus volumineux
  • Désavantages:
    1. En cas de panne, les dernières données de sauvegarde peuvent être perdues
    2. La mémoire occupée par le processus enfant sera exactement la même que le processus parent, ce qui entraînera une charge sur le processeur
    3. La sauvegarde complète planifiée étant une opération lourde, elle ne peut pas être traitée pour une sauvegarde en temps réel

Configurer RDB:

  1. Mécanisme d'économie:
  2. Ouvrez le mode de compression de fichier RDB
    rdbcompression: oui
  3. Vérifiez le fichier RDB (mais il y aura 10% de perte de mémoire)
    rdbchecksum: oui

Résumé : RDB convient à la récupération de grandes quantités de données, mais l'intégrité et la cohérence des données peuvent être insuffisantes. Cependant, peu importe ce que la RDB perd. De toute façon, c'est le cache. Si vous le perdez, vous le perdez.

AOF

AOF peut garantir l'intégrité des données.
Caractéristiques: 1. Enregistrer les opérations d'écriture demandées par les utilisateurs sous forme de journaux. Les opérations de lecture ne seront pas enregistrées.
2. Le fichier est ajouté au lieu d'être modifié.
3. Redis est restauré via AOF, qui consiste en fait à lire le journal et à réexécuter l'opération d'écriture

  • avantage:

    1. AOF peut être sauvegardé en quelques secondes. Si un problème survient, seule la dernière seconde de données sera perdue, ce qui augmente la fiabilité et l'intégrité des données.
    2. Il est ajouté sous forme de journal. Si le disque est plein, l'outil redis-check-aof sera exécuté
    3. Lorsque la quantité de données est trop importante, redis peut réécrire automatiquement le aof en arrière-plan. Lorsque redis continue d'ajouter le journal à l'ancien fichier, la réécriture est également très sûre et n'affectera pas les opérations de lecture et d'écriture du client.
  • Désavantage

    1. Pour les mêmes données, le fichier AOF sera plus volumineux que le fichier RDB
    2. Pour différents mécanismes de synchronisation, AOF sera plus lent que RDB, car AOF sauvegardera pour les opérations d'écriture toutes les secondes.

Configurer AOF

Utilisez RDB ou AOF?

  • Si vous pouvez accepter une période de perte de cache, vous pouvez utiliser RDB
  • Si vous êtes plus préoccupé par les données en temps réel, utilisez AOF
  • Vous pouvez également utiliser RDB et AOF pour la persistance ensemble, RDB pour la sauvegarde à froid, vous pouvez restaurer différentes versions à des moments différents et AOF pour une sauvegarde à chaud pour vous assurer que les données ne sont perdues que pendant 1 seconde. Quand AOF est endommagé et indisponible, utilisez RDB pour le restaurer. Autrement dit, Redis charge d'abord l'AOF, et s'il y a un problème avec l'AOF, puis charge le RDB.

7. Configurez la réplication maître-esclave Redis pour séparer la lecture et l'écriture

Architecture maître-esclave


De manière générale, le mode maître-esclave utilise un maître et deux esclaves, mais en raison de fonds limités, un seul nœud esclave est utilisé dans la configuration suivante, c'est-à-dire un maître, un esclave et l'

autre mode maître-esclave: réplication sans disque, si le serveur Le disque dans le disque est un disque dur mécanique, et l'efficacité de lecture et d'écriture du disque peut être relativement faible.Si la bande passante du réseau est relativement bonne, le réseau peut être utilisé pour la transmission afin d'éviter l'interaction du disque.

réplication d'informations afficher l'état actuel du maître-esclave

Modifier la configuration du nœud esclave


Insérez la description de l'image ici


À ce stade, notre esclave, c'est-à-dire le nœud esclave, a été configuré et redémarré via redis_init_script sous /etc/init.d

Ajoutez des informations sur le nœud maître, qui peuvent être vues sur le nœud esclave, mais le nœud esclave ne peut pas écrire de données


Problèmes pouvant survenir lors de ce processus:Impossible de se connecter pour une raison quelconque? Il est recommandé de vérifier le replicaof dans le fichier redis.conf, c'est peut-être mon illusion, je ne sais pas pourquoi il sera automatiquement changé en 127.0.0.1Cela fait un peu peur. Comme vous pouvez le voir dans la capture d'écran ci-dessus, ce n'est pas normal.

Voici les informations correctes:

8. Mécanisme d'expiration du cache Redis et d'élimination de la mémoire

Comment gérer les clés expirées?

  1. Nettoyage de la synchronisation active: vérifiez périodiquement les clés expirées au hasard et effacez-les si elles expirent (fréquence de configuration HZ)
  2. Suppression paresseuse passive: lorsque le client demande une clé, si la clé expire, elle sera supprimée.

(Par conséquent, bien que la clé ait expiré, elle occupe toujours la mémoire tant qu'elle n'est pas nettoyée)

Et si la mémoire est pleine? Mécanisme d'élimination de la mémoire

Neuf, mécanisme de sentinelle

En mode maître-esclave, que dois-je faire lorsque le nœud maître tombe en panne? Cela rendra l'écriture impossible et le nœud esclave ne pourra pas être utilisé.
Le mécanisme sentinelle peut être utilisé pour le contrôle. Lorsque le nœud principal est tué, la sentinelle peut être utilisée pour définir le nœud enfant comme nœud principal.

Configurer la sentinelle

Basculement

Lorsqu'une sentinelle du cluster sentinelle constate que le maître est en panne, elle ne peut pas décider d'effectuer un basculement ou un basculement maître-esclave. Parce que dans l'environnement réseau, il peut y avoir des jugements erronés causés par des problèmes de réseau. Cela s'appelle subjectif hors ligne.
Lorsque plusieurs sentinelles trouvent qu'il y a un problème avec ce nœud (objectif hors ligne), le basculement est effectué. Basculement
: transformez l'esclave en maître pour continuer le service. Ce processus est exécuté par un chef parmi de nombreuses sentinelles, et le chef doit être élu (la minorité obéit à la majorité).

Lorsqu'une sentinelle obtient plusieurs votes, elle est appelée le chef, qui convertit l'esclave d'origine en maître, puis synchronise les informations du nouveau maître avec l'esclave.
Si le Maître précédent récupère, le Maître précédent rejoindra en tant qu'esclave.

Accord

  • La sentinelle a au moins trois nœuds, ou un nombre impair de nœuds. (Élections faciles à mener, la minorité obéit à la majorité)
  • Les sentinelles doivent être déployées sur différents nœuds informatiques. (S'ils sont tous sur le même nœud, lorsque le nœud est en panne, la sentinelle est également morte, cela n'a pas de sens)
  • Un groupe de sentinelles ne surveille qu'un groupe de maître et d'esclave.

10. Redis cluster: multi-maître et multi-esclave

Inconvénients d'un maître: lorsque l'ancien maître est arrêté, un basculement maître-esclave est effectué à ce moment. Cependant, si de nouvelles opérations d'écriture surviennent à ce moment, elles seront perdues. Il y a donc plusieurs maîtres et plusieurs esclaves

Nœud de fente

Les données de redis sont stockées dans le noeud de l'emplacement. Une

fois les données hachées, le module est obtenu pour obtenir l'emplacement de stockage.

11. Pénétration du cache

Qu'est-ce que la pénétration du cache?
Pour certaines données chaudes, nous existons dans redis, le but est de réduire la quantité d'accès à la base de données. Cependant, si des utilisateurs illégaux attaquent le système et transmettent des valeurs qui n'existent pas du tout. Selon la logique précédente, ils iront d'abord à redis pour les trouver. S'ils ne peuvent pas les trouver, ils iront dans la base de données pour vérifier. Si elles ne sont pas traitées, la base de données sera endommagée. Le nombre de visites a augmenté, et finalement il a diminué. Comment bloquer cet accès illégal?

1. Stockez la valeur nulle obtenue à partir des informations demandées par des utilisateurs illégaux dans Redis pour protéger les attaques sur la base de données

List<CategoryVO> list = new ArrayList<>();
        String subCatsStr = redisOperator.get("subCat:"+rootCatId);
        if (StringUtils.isBlank(subCatsStr)) {
    
    
            list = categoryService.getSubCatList(rootCatId);

            if (list!=null && list.size()>0){
    
    
                redisOperator.set("subCat:"+rootCatId, JsonUtils.objectToJson(list));
            }else {
    
    
                /*
                * 若被非法用户攻击(疯狂访问数据库,使数据库宕机)
                * 即缓存穿透
                * 解决方法:将用户非法的请求得到的空数据也缓存在redis中,避免直接访问数据库
                * */
                redisOperator.set("subCat:"+rootCatId, JsonUtils.objectToJson(list),5*60);
            }
        } else {
    
    
            list = JsonUtils.jsonToList(subCatsStr, CategoryVO.class);
        }
        return IMOOCJSONResult.ok(list);

2. Filtre Bloom


Pour chaque clé, après une certaine opération, enregistrez-la à une certaine position sur le tableau et définissez-la sur 1.
Lorsqu'une valeur illégale arrive, elle ne peut pas correspondre à 1, et même redis n'entrera pas (évidemment, il y aura des erreurs) Phrase)

Inconvénients du filtre Bloom:

  1. Impossible de supprimer les données (plusieurs données existent au même emplacement)
  2. Mauvaise évaluation
  3. Plus le taux d'erreur est faible, plus l'espace occupé est grand
  4. Pour maintenir une collection et interagir avec redis

12. Cache avalanche

Le cache de Redis est arrivé à échouer dans une grande zone à un certain moment, et un grand nombre de demandes se sont produites à ce moment, entraînant un temps d'arrêt de la base de données

Treize, requête par lots Redis


Vous pouvez créer un pipeline pour effectuer plusieurs requêtes clés à la fois

Je suppose que tu aimes

Origine blog.csdn.net/qq_44357371/article/details/109367400
conseillé
Classement