Maison  >  Article  >  base de données  >  Résoudre le problème de l'inventaire survendu dans Redis

Résoudre le problème de l'inventaire survendu dans Redis

coldplay.xixi
coldplay.xixiavant
2021-03-18 10:49:422851parcourir

Résoudre le problème de l'inventaire survendu dans Redis

MQ est utilisé entre les biens et les services de commande

Lorsque l'inventaire des biens et services change, le service de commande l'inventaire est notifié via le changement MQ.

Processus de synchronisation d'origine

  1. Rechercher des informations sur le produit (appeler le service produit)
  2. Calculer le prix total (générer les détails de la commande)
  3. Déduire l'inventaire des biens et services (appeler les biens et services)
  4. Commander l'entreposage (générer des commandes)
// 原始的MySQL同步流程// 判断此代金券是否加入抢购SeckillVouchers seckillVouchers = seckillVouchersMapper.selectVoucher(voucherId);AssertUtil.isTrue(seckillVouchers == null, "该代金券并未有抢购活动");// 判断是否有效AssertUtil.isTrue(seckillVouchers.getIsValid() == 0, "该活动已结束");// 插入数据库seckillVouchersMapper.save(seckillVouchers);

Recommandé (gratuit) : redis

Déduire l'inventaire directement lorsqu'une commande est générée. C'est le système de déduction d'inventaire le plus original. Il est relativement simple, mais il y a des

problèmes<.>

    De nombreuses commandes peuvent déduire l'inventaire des produits sans paiement. Cela nécessite un script en arrière-plan pour libérer l'inventaire des commandes qui n'ont pas été payées pendant un certain temps et annuler la commande
  • Déduisez immédiatement l'inventaire , Différence de concurrence
  • 1. Service produit en 3 étapes, base de données opérationnelle du service produit, 2. Service de commande en 4 étapes, base de données opérationnelle du service de commande.

Évitez d'accéder à la base de données de différents services. En principe, un même service ne peut exploiter que la base de données de son propre service.

Asynchronisation MQ

Considérez d'abord l'asynchrone uniquement l'étape 4.

Analyse

2 et 4 sont toutes des opérations sur la base de données. L'étape 4 n'attend plus. Les commentaires seront donnés à l'utilisateur immédiatement après le succès des étapes 1. , 2 et 3.

Après cela, la commande sera passée de manière asynchrone via le service de notification de message. Si le placement de commande asynchrone échoue à l'étape 4, réessayez l'opération et essayez de régénérer la commande. Les messages MQ peuvent également être retracés.


Une fois la commande créée, elle est dans l'état de file d'attente, puis le service publie un événement dans la file d'attente des messages.
Autrement dit, le service de commande envoie un message au monde extérieur : j'ai créé une commande, qui a été transmise par MQ au service qui a souscrit au message. Order Created

Si le service produit reçoit le message de création de commande, il effectuera l'opération de déduction des stocks. Notez que la déduction des stocks peut échouer en raison de certains facteurs de force majeure. Quel que soit le succès ou l'échec, le service produit enverra un message de déduction des stocks à MQ, et le contenu du message est le résultat de la déduction des stocks.

Le service de commande s'abonnera au résultat de la déduction de l'inventaire. Après avoir reçu le message :


Si la déduction de l'inventaire réussit, le statut de la commande passera à
    , c'est-à-dire la commande est passée avec succès
  • 已确认Si la déduction d'inventaire échoue, modifiez le statut de la commande en
  • , c'est-à-dire que la commande a échoué
  • 已取消
  • Pour répondre aux exigences du modèle ci-dessus, message fiable la livraison est obligatoire. Les messages envoyés par le service seront définitivement reçus par MQ.

Changements dans l'expérience utilisateur
    Le front-end coopère avec l'interface du support de file d'attente.

  • Les services de produits/commandes sont devenus asynchrones, ce qui convient aux scénarios de vente flash. Ce n'est pas très adapté lorsque le trafic n'est pas important.

Conception asynchrone

L'inventaire est enregistré dans Redis
  1. Après avoir reçu la demande, Redis détermine si l'inventaire est suffisant et soustrait l'inventaire dans Redis
  2. Le service de commande crée une commande et l'écrit dans la base de données, et envoie un message
  3. Lorsque le paiement de la commande est réussi, il y aura un processus sortant depuis là. Dans ce processus, la livraison sortante peut échouer.
L'inventaire comporte deux parties :


Couche redis du cache
  • Couche mysql de la base de données
Lorsque le service client ajoute 5 nouveaux inventaires, Ensuite, les couches de cache Redis et de base de données MySQL doivent ajouter 5 inventaires et utiliser la cohérence finale des transactions distribuées pour répondre aux exigences : soit tous les inventaires sont ajoutés, soit aucun n'est ajouté.
  1. Lorsqu'une commande est générée, l'inventaire doit être déduit,
  2. Si la déduction réussit, une commande est générée pour le paiement. Ce processus est
  3. . 先扣redis库存不扣除mysql库存Lorsque l'inventaire Redis est déduit, le produit ne peut pas être commandé et la commande échouera, la couche externe est donc bloquée.
  4. A l'étape 2
  5. , générez la commande, effectuez le paiement, le paiement est réussi, retournez dans mon centre de commande, et vous constaterez qu'il y a un processus sortant.
  6. 扣除redis库存成功后
  7. Une file d'attente de tâches découplée asynchrone MQ, le processus est 出库过程 :
    扣除mysql库存
Si l'inventaire mysql est déduit avec succès, l'export est réussi , Terminez tout le processus de passation d'une commande et entrez le statut de livraison
  • Si l'inventaire mysql ne parvient pas à être déduit et que l'expédition échoue, effectuez une série d'opérations
  • Le statut de la commande est modifié en annulé
    • Renvoyer l'inventaire redis
    • Remboursement
inventaire redis et inventaire mysql

avant le paiement est

, est

, c'est le processus de verrouillage de l'inventaire 预扣 Il est effectivement déduit après le paiement, 扣redis库存, garantissant que l'inventaire est finalement cohérent
扣mysql库存 Cependant, dans dans les cas extrêmes, il y aura des incohérences de données

Si stock redis = stock mysql, il n'y aura pas de problème
  • Si stock redis
  • Si l'inventaire redis > l'inventaire mysql, il sera survendu. Les commandes survendues échoueront pendant le processus sortant
  • De cette façon. , il n'y aura globalement aucun problème. La couche de base de données mysql garantit que l'inventaire ne sera pas publié à la fin.

Question

L'inventaire de la base de données et l'inventaire Redis sont incohérents, comment le détecter ?

Si une incohérence est détectée, comment synchroniser

Je n'ai pas trouvé de bon plan
Une méthode plus violente consiste à trouver un période de pointe faible, comme à 1 heure du matin, couverture forcée périodique. Cependant, dans des cas extrêmes, il peut encore y avoir des inexactitudes après la synchronisation. Par exemple, pendant le processus de synchronisation, une commande est payée avec succès, l'inventaire MySQL est déduit pendant le processus sortant, mais le paiement est effectué. L'inventaire Redis n'est pas déduit

Il s'agit d'un problème avec le mécanisme de mise à jour du cache de synchronisation de la base de données
C'est un problème de conception logique cohérente
缓存数 = 数据库库存数 - 待扣数
Bien sûr, il y en a. d'autres solutions, ainsi que des considérations En fonction du niveau d'exigences de cohérence, des solutions simples ou complexes peuvent être utilisées
Cela dépend de la complexité du système. Plus le système est grand, plus il sera détaillé
Pour. exemple, le numéro à déduire peut être placé dans une file d'attente ou mis en cache Il y a aussi un décompte à l'intérieur, il suffit de lire le décompte directement
Par exemple, si vous le mettez en mongo, la quantité qui a été payée et qui doit être Les expéditions ne sont généralement pas très volumineuses. Si vous le comptez, vous ne perdrez pas grand-chose
Par conséquent, le système général ne peut pas être complètement Pour garantir que la chaîne de données ne commet pas d'erreurs, il doit y avoir une compensation, c'est-à-dire des erreurs. peut être corrigé
Le coût pour s'assurer qu'il n'y a pas d'erreurs est évidemment trop élevé
La synchronisation a un mécanisme de rafraîchissement, qui peut être planifié, soit via MQ, soit par surveillance Non synchronisé et ainsi de suite. . .
Également appelé assurer la fraîcheur des données mises en cache
Généralement, cela ne prend pas trop de temps, cela peut prendre une demi-heure ou quelques minutes Différents scénarios ont des besoins différents

12306<.>

12306 qui achètent des billets de train ne peuvent pas acheter de billets la nuit. Ce temps est estimé comme étant la synchronisation de l'inventaire et la synchronisation de l'inventaire de la base de données avec l'inventaire redis. Cependant, lors de l'achat de billets de train, le montant réel doit être déduit avant le montant réel. La commande est générée. L'inventaire, c'est-à-dire que l'inventaire de mysql doit être déduit

Parce que l'achat d'un billet de train est différent du shopping. Les achats peuvent être expédiés hors de l'entrepôt après le paiement, mais l'achat d'un billet doit être effectué. être expédié hors de l'entrepôt avant le paiement. Par conséquent, l'inventaire sortant doit être déduit de l'inventaire. Ce n'est que lorsque l'entrepôt est expédié avec succès qu'une commande peut être générée. Il est également nécessaire d'introduire l'inventaire redis

pour déduire d'abord l'inventaire dans le cache. Une fois la déduction réussie, l'inventaire dans MySQL peut ensuite être déduit.

Si l'inventaire dans le cache ne parvient pas à être déduit, il sera bloqué et un inventaire insuffisant sera renvoyé. Ces requêtes ne seront pas perforées dans MySQL, bloquant la majeure partie de la pression des requêtes.

L'inventaire Redis sera incohérent avec l'inventaire mysql. Dans les cas extrêmes, c'est certainement le cas. La synchronisation de l'inventaire est requise

    Lors du cache. l'inventaire est supérieur à l'inventaire de la base de données. S'il y en a trop, il apparaîtra qu'il y a des tickets dans la requête, mais la commande ne peut pas être passée. Lors de la passation de la commande, il est dit que le stock est insuffisant. entraînera une pression excessive sur la base de données. Cependant, 12306 devrait avoir d'autres moyens pour éviter ce problème, mais j'ai effectivement rencontré une situation où j'avais des billets lors de la vérification, mais je ne pouvais pas passer de commande.
  • Lorsque l'inventaire du cache est inférieur au cache de la base de données, il n'y aura aucun problème. Il n'y aura que des billets mais aucune vente. Une fois la synchronisation de l'inventaire terminée, il sera à nouveau précis. demain.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer