Maison > Article > base de données > Comment Redis réalise-t-il des mises à jour de pages en temps réel et des mises à jour automatiques en ligne ?
Certaines pages doivent être configurées avec des publicités ou des images de promotion d'événements. Les publicités ou les activités doivent pouvoir être mises en ligne et hors ligne à tout moment, se déconnecter automatiquement après l'expiration et se mettre automatiquement en ligne le moment venu.
Par exemple : l'heure actuelle est le 22/02/2019 16:16:13 Pour configurer l'activité de collecte des prix sur la page de finalisation du paiement, l'activité doit être en ligne à l'heure au 10/03/2019 00:00:00. et le 30/03/2019 23 :59:59 Fin d'activité.
Par conséquent, l'effet recherché est qu'après avoir configuré l'activité à tout moment avant la mise en ligne de l'activité, la page se mettra automatiquement en ligne à l'heure spécifiée. Il peut également y avoir plusieurs autres activités ou publicités. Le nombre de publicités sur chaque page est variable, et les heures en ligne et hors ligne peuvent être différentes pour différentes pages. D'autres pages doivent également mettre en œuvre de telles fonctions, et les activités entre les pages ne le sont pas nécessairement. le même.
Les exigences ne sont que quelques mots, alors analysons-les en détail.
Photos de publicité ou de promotion d'un événement
En ligne et hors ligne à tout moment, automatiquement hors ligne à l'expiration et automatiquement en ligne le moment venu
Le nombre d'annonces sur chaque page est variable
Différentes annonces Les horaires en ligne et hors ligne peuvent être différents
Les activités entre les pages ne sont pas nécessairement les mêmes
1 [Photos de publicité ou de promotion d'un événement]
Pour définir différentes annonces pour différentes. pages, certaines pages Les publicités peuvent être les mêmes, c'est-à-dire que les publicités seront réutilisées, il doit donc y avoir une table de publicités.
2. [Le nombre de publicités sur chaque page est variable] [Les horaires en ligne et hors ligne des différentes publicités peuvent être différents] [Les activités entre les pages ne sont pas nécessairement les mêmes]
Une page peut être configurée avec plusieurs publicités, toutes dont nécessitent une table de configuration de page et la table de relations entre les publicités et les pages, c'est-à-dire la table de publicité de page.
Le tableau de configuration de la page configure principalement le nombre de publicités sur la page à réaliser [le nombre de publicités sur chaque page est variable]. Le tableau de publicité de la page configure principalement le temps en ligne et hors ligne de chaque publicité sur la page à réaliser [la table de configuration de la page] les heures en ligne et hors ligne des différentes publicités peuvent être différentes]
Sur la base d'une analyse simple, je suis arrivé à la structure de table suivante : table de publicité (adv), table de configuration de page (page_config) et table de publicité de page (page_adv)
Les publicités configurées sur ces pages ne changeront pas pendant un certain temps. Si le nombre de requêtes de pages est élevé, le nombre de requêtes publicitaires sera très fréquent, provoquant une pression inutile sur la base de données. Par conséquent, la mise en cache peut être introduite pour réduire le nombre de requêtes de base de données et soulager la pression sur la base de données. Redis est utilisé ici.
Quand sera-t-il mis en cache ?
Vous pouvez choisir de charger de manière asynchrone les annonces qui ont été dans les intervalles de temps en ligne et hors ligne dans le cache lorsque le service démarre, ou choisir de récupérer le cache lorsque la demande est effectuée. Si le cache n'existe pas, vérifiez le. bibliothèque et mettez-la dans le cache. Le temps de mise en cache dépend de la situation.
Le choix ici est de stocker de manière asynchrone les informations de configuration publicitaire des pages éligibles dans Redis lorsque le projet démarre. Celles qui n'ont pas encore atteint l'heure spécifiée ne seront pas mises dans Redis en premier lors de l'accès à la page pour charger la publicité. Redis sera vérifié en premier. S'il n'y en a pas, appuyez sur Condition (>=nowtime) pour vérifier la base de données et la stocker dans Redis après vérification.
Après avoir obtenu les informations de configuration de la publicité dans l'interface, déterminez si l'heure actuelle se situe dans l'intervalle de temps configuré. Étant donné que plusieurs publicités sont configurées sur une page, les différentes heures de publicité sont différentes, il est donc nécessaire de parcourir et de renvoyer celles qui le sont. correspondent et ceux expirés, marquez-le, puis supprimez les informations de configuration de la page entière dans Redis. (Ou ne choisissez pas de charger au démarrage, ajoutez simplement le cache lorsque l'utilisateur le demande, mais la méthode de l'étape 1 ci-dessous sera utilisée lors de l'actualisation du chargement, il ne peut donc pas être supprimé)
a, interrogez tous les pageId
SELECT pageId FROM page_config page_adv WHERE nowtime<p> et joignez les deux tables pour obtenir List<pageid>. Ce que vous obtenez, ce sont tous les identifiants de page configurés avec des publicités et les publicités ne l'ont pas été. expiré. </pageid></p><p>b. Recherchez l'image publicitaire et le lien de saut correspondant à pegeId</p><pre class="brush:php;toolbar:false">SELECT 字段名 FROM page_adv adv WHERE begintime<p>Puis mettez les informations de configuration trouvées List<adv> (aucune opération ne sera effectuée si elle est vide), et mettez le pageId comme KEY dans le cache. </adv></p><h4>Étape 2. Écrivez une interface pour le front-end pour interroger les publicités des pages</h4><p>Écrit selon la couche de contrôle standard, la couche métier et la couche d'accès aux données. La logique de la première étape est complétée dans la couche métier. </p><p>Couche de contrôle : </p><p>La couche de contrôle reçoit le paramètre pageId, appelle la couche métier pour interroger les informations publicitaires configurées sur la page correspondante, détermine qu'elle est vide et renvoie directement le code d'état 0, c'est-à-dire qu'il n'y a pas de publicité et le frontal ne l'affiche pas. </p><p>S'il n'est pas vide, les données seront traitées selon la logique métier (comme l'URL d'img plus le nom de domaine), puis le code d'état 1 sera renvoyé et le front-end affichera la publicité. La couche de contrôle peut également ajouter une logique ici pour parcourir la liste d'annonces, renvoyer l'heure actuelle dans l'heure de début de l'annonce et ne pas renvoyer celles qui ne sont pas là. Et tant qu'une annonce expire, le cache de la liste d'annonces de cette page le sera. être effacé. La logique est d’éliminer ceux qui sont expirés. </p><p>Couche métier : </p><p>Récupérez d'abord le cache, puis vérifiez la base de données pour déterminer qu'elle n'est pas vide (cette page est configurée avec des publicités), placez-la dans le cache (pageId est KEY), puis revenez. </p><p>Couche d'accès aux données : </p><p>SQL :</p><pre class="brush:php;toolbar:false">SELECT 字段名 FROM page_config adv page_adv WHERE begintime<p>Requête conjointe à trois tables, interroge les informations de campagne publicitaire configurées sur la page actuelle en fonction de l'ID de page (déjà pendant la durée de la campagne publicitaire)</p><h4>Étape 3, actualiser le chargement</h4><p>Pourquoi utiliser Actualiser le chargement ? </p><p>因为有这样的场景:给页面A配置了一个广告(当前时间在广告的起始时间内),那么这个页面的广告已经在缓存里了,假如此时A页面要新加一个广告,在后台配置后如果不做其他操作,这个广告不会显示(假设缓存时间较长,为一天),因为库更新了,缓存没有同步更新。</p><p>解决方案</p><p>使用Redis的发布订阅机制实现缓存的刷新加载,使新配置的广告及时能够显示。刷新加载的回调方法即第1步中的方法。</p><h3>进一步优化</h3><p>想一想,目前的实现存在什么问题?</p><p>存在的问题</p><p>假如有页面需要配置广告,但是还没有配(前端已经开发完上线,每次都会调接口查广告信息),那么数据库肯定查不到,缓存也没有。如果这个页面访问量很大,那么缓存没命中就查库,这样对库的压力就会很大,这就是缓存穿透,请求上来了很容易击垮数据库。那怎么办呢?</p><p>解决方案</p><p>当页面没有配置广告时,在缓存存标志,查询时先看标志,在决定是否往下走。</p><p>具体方案</p><p>这时,上面的第1步就要改了。</p><p>1、首先改第1步的步骤a的SQL,把所有的pageId都查询出来。</p><p>使用左连接</p><pre class="brush:php;toolbar:false">SELECT pageId FROM page_config LEFT JOIN page_adv ON ... GROUP BY pageId
或者干脆查page_config
SELECT pageId FROM page_config
目的是把已在page_config表中配置,但关系表中page_adv未配置广告的pageId也查出来,这样才能给未配置广告的pageId在缓存里放标志
2、第1步的步骤b的SQL改为
SELECT 字段名 FROM page_adv adv WHERE nowtime<p>然后把查到的配置信息放入缓存之前判断【为空时的不做操作】改为【为空时存入一个标志】假如这个标志KEY为pageId+"_EMPTY_FLAG",value为"DB_IS_NULL"</p><p>为什么只判断小于结束时间</p><p>因为如果该页面配置的广告开始时间大于当前时间,那么这个是查不到的,会被处理为DATABASE_IS_NULL,如果在这个标志还没失效之前就到了配置的开始时间了,那么这个广告不会被展示。所有要让未到开始时间的也放入缓存,然后让控制层去判断在不在时间区间。</p><p>3、所以要在第2步也修改一下</p><p>在业务层里取缓存中的广告列表之前,先从缓存取pageId+"EMPTY_FLAG"的value判断为"DB_IS_NULL"直接返回空,这样就能避免缓存穿透的问题了。</p><p>继续修改第2步的业务层,查库的SQL同样要改:</p><pre class="brush:php;toolbar:false">SELECT 字段名 FROM page_config adv page_adv WHERE nowtime<p>然后判断为空的话,同上面的黄字那样处理。</p><p>4、最后,第3步的刷新加载调的是第1步的方法,不用改。<br><br>当然这个缓存穿透的优化方案只是其中一种。还可以这样:</p><p>1、控制层拦截:根据pageId查询page_adv表,查不到说明没配置,直接返回。</p><p>2、page_config 表增加字段,表示当前页面已经配置的广告个数,默认0,每配置一个该字段加1,把大于0的pageId缓存起来,调接口时前判断在不在缓存里。</p>
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!