ホームページ  >  記事  >  データベース  >  Redis はどのようにしてリアルタイムのページ更新と自動オンライン更新を実現しているのでしょうか?

Redis はどのようにしてリアルタイムのページ更新と自動オンライン更新を実現しているのでしょうか?

WBOY
WBOY転載
2023-06-03 20:56:171329ブラウズ

要件の説明

一部のページには、広告またはイベントのプロモーション画像を設定する必要があります。広告またはアクティビティはいつでもオンラインとオフラインに切り替えることができ、有効期限が切れると自動的にオフラインになり、自動的にオンラインになる必要があります。時が来たら。

例: 現在の時刻は 2019-2-22 16:16:13 です。支払い完了ページで報酬収集アクティビティを設定する必要があります。アクティビティは 2019 年 3 月に予定どおりに開始される必要があります。 10 00:00:00. 2019年- イベントは3 30 23:59:59に終了しました。

したがって、望ましい効果は、アクティビティがオンラインになる前の任意の時点でアクティビティを構成した後、指定された時刻にページが自動的にオンラインになることです。他にも複数のアクティビティや広告がある場合があります。各ページの広告の数は変化し、オンライン時間とオフライン時間はページによって異なる場合があります。他のページにもそのような機能を実装する必要があり、ページ間のアクティビティは必ずしも必要ではありません同じ。

要件分析

要件はほんの数語なので、詳しく分析してみましょう。

キーワードの抽出

  • 広告またはイベントのプロモーション写真

  • いつでもオンラインとオフラインに切り替え、有効期限が切れると自動的にオフラインになります。オンライン

  • 各ページの広告の数は可変です

  • 広告ごとにオンライン時間とオフライン時間は異なる場合があります

  • ページ間のアクティビティは必ずしも同じであるとは限りません

データベース分析

1. [広告またはイベントのプロモーション写真]

To be Different ページには異なる広告があり、一部のページの広告は同じである可能性があります。つまり、広告は再利用されるため、広告テーブルが必要です。

2. [各ページの広告の数は変動します] [広告ごとにオンライン時間とオフライン時間が異なる場合があります] [ページ間のアクティビティは必ずしも同じであるとは限りません]

複数のページ各広告には、ページ構成テーブルと、広告とページの関係テーブル、つまりページ広告テーブルが必要です。

ページ構成テーブルは、[各ページの広告数が可変] を実現するために、主にページ上の広告数を構成します。ページ広告テーブルは、主に、ページ上の各広告のオンライン時間とオフライン時間を構成します。 [オンラインとオフラインで異なる広告] を実現するには、時間が異なる場合があります]

簡単な分析に基づいて、次のテーブル構造にたどり着きました: 広告テーブル (adv)、ページ構成テーブル (page_config)、およびページ広告テーブル(page_adv)

Redis はどのようにしてリアルタイムのページ更新と自動オンライン更新を実現しているのでしょうか?

考え方

これらのページに設定された広告は一定期間内に変更されません。ページのリクエスト数が多いと、広告のクエリ数が非常に頻繁になり、不要なプレッシャーが発生します。データベース上で。したがって、キャッシュを導入してデータベース要求の数を減らし、データベースの負担を軽減することができます。ここではRedisを使用します。

いつキャッシュされますか?

サービスの開始時に、オンラインおよびオフラインの時間間隔に存在したアドバタイズメントを非同期的にキャッシュにロードするか、リクエストが行われたときにキャッシュをフェッチするかを選択できます。 、ライブラリを確認してキャッシュに入れます。キャッシュ時間は状況によって異なります。

ここでの選択は、プロジェクトの開始時に、対象となるページの広告設定情報を Redis に非同期的に保存することです。指定された時間に達していないものは、最初に Redis に保存されません。ページがアクセスされたときアドバタイズメントをロードすると、最初に Redis がチェックされますが、そうでない場合は、条件 (>=nowtime) に従ってデータベースをチェックし、チェックした後、Redis に保存します。

インターフェースで広告設定情報を取得した後、現在時刻が設定された時間間隔内であるかどうかを判断します。ページ上に複数の広告が設定されているため、異なる広告時間も異なるため、反復する必要があります期限切れのものにマークを付けて、Redis のページ全体の構成情報を削除します。 (または、起動時にロードすることを選択せず​​、ユーザーが要求したときにキャッシュを追加します。ただし、以下の手順 1 のメソッドはロードを更新するときに使用されるため、削除できません)

具体的な実装

ステップ 1. プロジェクトが開始されたら、まずページ広告構成情報を Redis

#a に保存し、すべての pageId

SELECT pageId FROM page_config page_adv WHERE nowtime をクエリし、2 つのテーブルを接続して List&lt を取得します。 ;pageId> と取得し、すべてを取得します。これは、広告が設定されている pageId であり、広告の有効期限が切れていません。 <p></p>b. pegeId<p></p><pre class="brush:php;toolbar:false">SELECT 字段名 FROM page_adv adv WHERE begintimeに対応する広告画像とジャンプリンクをクエリし、見つかった設定情報List<adv>(空の場合は何も実行されません)を配置し、pageIdを使用しますKEY.としてキャッシュに保存されます。 <p></p>ステップ 2. フロント エンドのインターフェイス クエリ ページ アドバタイズメントを作成します。<h4></h4>標準の制御層、ビジネス層、およびデータ アクセス層に従って作成されます。最初のステップのロジックは次のように完成します。ビジネス層。 <p></p>コントロール レイヤー: <p></p>コントロール レイヤーは、パラメーター pageId を受け取り、ビジネス レイヤーを呼び出して、対応するページに設定されている広告情報をクエリします。空の場合は、ステータス コード 0 を直接返します。つまり、広告はなく、フロントエンドは広告を表示しません。 <p></p>空でない場合、データはビジネス ロジック (img URL とドメイン名など) に従って処理され、ステータス コード 1 が返され、フロントエンドで広告が表示されます。 。コントロール レイヤは、ここにロジックを追加して、広告リストを反復し、広告開始時刻内の現在時刻を返し、そこに存在しない時刻は返さないようにすることもできます。また、広告の有効期限が切れている限り、このページの広告リスト キャッシュは次のようになります。クリアされる。ロジックは、期限切れのものを削除することです。 <p></p>ビジネス層: <p></p>最初にキャッシュを取得し、次にデータベースをチェックして空でないかどうかを確認し (このページには広告が設定されています)、キャッシュに入れます (pageId は KEY)。 、そして戻ります。 <p></p>データ アクセス レイヤー: <p></p>SQL:<p></p>
<pre class="brush:php;toolbar:false">SELECT 字段名 FROM page_config adv page_adv WHERE begintime3 つのテーブルの結合クエリ。pageId に基づいて現在のページに設定されている広告活動情報をクエリします (広告活動時間内にすでに存在します)。 )<p></p>ステップ 3、読み込みの更新<h4></h4>なぜ読み込みの更新を使用するのですか? <p></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>

以上がRedis はどのようにしてリアルタイムのページ更新と自動オンライン更新を実現しているのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。