>  기사  >  데이터 베이스  >  Redis는 실시간 페이지 업데이트와 자동 온라인 업데이트를 어떻게 실현합니까?

Redis는 실시간 페이지 업데이트와 자동 온라인 업데이트를 어떻게 실현합니까?

WBOY
WBOY앞으로
2023-06-03 20:56:171270검색

요구사항 설명

일부 페이지는 광고나 이벤트 프로모션 이미지로 구성되어야 합니다. 광고나 활동은 언제든지 온라인 및 오프라인으로 전환될 수 있어야 하며, 만료 후 자동으로 오프라인으로 전환되고, 때가 되면 자동으로 온라인으로 전환될 수 있어야 합니다.

예: 현재 시간은 2019-2-22 16:16:13입니다. 결제 완료 페이지에서 보상 수집 활동을 구성하려면 활동이 2019-3-10 00:00:00 시간에 온라인이어야 합니다. 2019-3-30 23 :59:59 활동 종료.

따라서 원하는 효과는 활동이 온라인으로 전환되기 전 언제든지 활동을 구성한 후 지정된 시간에 페이지가 자동으로 온라인으로 전환되는 것입니다. 또한, 여러 다른 활동이나 광고가 있을 수 있으며, 각 페이지의 광고 수는 다양하며, 페이지마다 온라인 및 오프라인 시간이 다를 수 있으며, 다른 페이지에서도 이러한 기능을 구현해야 하며 페이지 간 활동이 반드시 필요한 것은 아닙니다. 똑같다.

요구사항 분석

요구사항은 몇 단어에 불과하므로 자세히 분석해 보겠습니다.

키워드 추출

  • 광고 또는 이벤트 프로모션 사진

  • 온라인 및 오프라인 상시, 만료되면 자동 오프라인, 때가 오면 자동 온라인

  • 각 페이지의 광고 수는 가변적입니다

  • 다른 광고 온라인과 오프라인 시간은 다를 수 있습니다

  • 페이지 간 활동이 반드시 동일하지는 않습니다

데이터베이스 분석

1. [광고 또는 이벤트 홍보 사진]

다른 광고를 설정하려면 페이지, 일부 페이지의 광고는 동일할 수 있습니다. 즉, 광고가 재사용되므로 광고 테이블이 있어야 합니다.

2. [페이지별 광고 개수는 가변적임] [광고별로 온라인 및 오프라인 시간이 다를 수 있음] [페이지 간 활동이 반드시 동일할 필요는 없음]

한 페이지에 여러 개의 광고가 구성될 수 있으며, 모두 그 중 페이지 구성 테이블이 필요하며, 광고와 페이지 간의 관계 테이블, 즉 페이지 광고 테이블이 필요합니다.

페이지 구성 테이블은 주로 페이지의 광고 수를 구성하여 [각 페이지의 광고 수는 가변적]을 구현합니다. 페이지 광고 테이블은 주로 페이지의 각 광고의 온라인 및 오프라인 시간을 구성하여 [ 온라인과 오프라인 광고 시간은 다를 수 있음]

간단한 분석을 통해 다음과 같은 테이블 구조를 생각해냈습니다: 광고 테이블(adv), 페이지 구성 테이블(page_config), 페이지 광고 테이블(page_adv)

Redis는 실시간 페이지 업데이트와 자동 온라인 업데이트를 어떻게 실현합니까?

Thinking

이 페이지에 구성된 광고는 일정 기간 동안 변경되지 않습니다. 페이지 요청 수가 많으면 광고 쿼리 수가 매우 빈번해져 데이터베이스에 불필요한 부담이 발생합니다. 따라서 캐싱을 도입하여 데이터베이스 요청 수를 줄이고 데이터베이스 부담을 완화할 수 있습니다. 여기서는 Redis를 사용합니다.

언제 캐시되나요?

서비스가 시작될 때 온라인 및 오프라인 시간 간격에 있던 광고를 캐시에 비동기적으로 로드하도록 선택하거나, 캐시가 존재하지 않는 경우 캐시를 가져오도록 선택할 수 있습니다. 라이브러리를 캐시에 넣습니다. 캐싱 시간은 상황에 따라 다릅니다.

여기서 선택할 수 있는 방법은 프로젝트가 시작될 때 적격 페이지의 광고 구성 정보를 Redis에 비동기적으로 저장하는 것입니다. 아직 지정된 시간에 도달하지 않은 페이지는 광고를 로드하기 위해 페이지에 액세스할 때 Redis에 먼저 저장되지 않습니다. Redis가 먼저 확인됩니다. 아무것도 없으면 조건(>=nowtime)을 눌러 데이터베이스를 확인하고 확인 후 Redis에 저장합니다.

인터페이스에서 광고 구성 정보를 얻은 후 현재 시간이 구성된 시간 간격 내에 있는지 확인합니다. 한 페이지에 여러 개의 광고가 구성되어 있으므로 광고 시간이 다르기 때문에 반복하여 반환해야 합니다. 일치하고 만료된 항목을 표시한 다음 Redis에서 전체 페이지의 구성 정보를 삭제합니다. (또는 시작 시 로드하도록 선택하지 않고 사용자가 요청할 때 캐시를 추가하기만 하면 됩니다. 그러나 로드를 새로 고칠 때 아래 1단계의 방법이 사용되므로 삭제할 수 없습니다.)

특정 구현

1단계, 프로젝트가 시작되면 먼저 Redis

a에 페이지 광고 구성 정보를 저장하고, 모든 pageIds

SELECT pageId FROM page_config page_adv WHERE nowtime<p>를 쿼리하고 두 테이블을 조인하여 List<pageid>를 가져옵니다. 얻는 것은 광고로 구성된 모든 페이지 ID이며 광고는 그렇지 않습니다. 만료되었습니다. </pageid></p><p>b. pegeId</p><pre class="brush:php;toolbar:false">SELECT 字段名 FROM page_adv adv WHERE begintime<p>에 해당하는 광고 이미지와 점프 링크를 쿼리한 다음, 찾은 구성 정보 List<adv>를 넣고(비어 있으면 작업이 수행되지 않음) pageId를 KEY로 캐시에 넣습니다. </adv></p><h4>2단계: 쿼리 페이지 광고에 대한 프런트 엔드용 인터페이스 작성</h4><p>표준 제어 계층, 비즈니스 계층 및 데이터 액세스 계층에 따라 작성되었습니다. 첫 번째 단계의 논리는 비즈니스 계층에서 완성됩니다. </p><p>컨트롤 레이어: </p><p>컨트롤 레이어는 매개변수 pageId를 수신하고 비즈니스 레이어를 호출하여 해당 페이지에 구성된 광고 정보를 쿼리합니다. 비어 있으면 상태 코드 0을 직접 반환합니다. 즉, 광고가 발생하지 않습니다. 프론트 엔드에 표시됩니다. </p><p>비어 있지 않으면 비즈니스 로직(예: img의 URL과 도메인 이름)에 따라 데이터가 처리된 다음 상태 코드 1이 반환되고 프런트 엔드에 광고가 표시됩니다. 제어 계층은 여기에 광고 목록을 반복하고, 광고 시작 시간 내의 현재 시간을 반환하고, 광고가 만료되는 한 광고 목록 캐시는 반환하지 않는 논리를 추가할 수도 있습니다. 지워졌습니다. 만료된 항목을 삭제하는 것이 논리입니다. </p><p>비즈니스 계층: </p><p>먼저 캐시를 가져온 다음 데이터베이스를 확인하여 비어 있지 않은지 확인하고(이 페이지는 광고로 구성됨) 캐시에 넣은 다음(pageId가 KEY임) 반환합니다. </p><p>데이터 액세스 계층: </p><p>SQL:</p><pre class="brush:php;toolbar:false">SELECT 字段名 FROM page_config adv page_adv WHERE begintime<p>3개의 테이블 공동 쿼리, pageId를 기반으로 현재 페이지에 구성된 광고 캠페인 정보 쿼리(이미 광고 캠페인 시간 내에 있음)</p><h4>3단계, 새로고침 로드</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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제