DB 数百万笔的庞大资料如何提供给 Client & 储存进 Redis cache 层的设计案例分享
前言
我遇到一个需求,需要将某张 Table 的所有资料提供 API 给客户
but!!那张 Table 的资料量高达 100 万笔,考量到资料库查询效能,不能对 Table 直接 Select All,并且考量到 API 的 response time 不能太久 & response size 不能太庞大, API 的 Client 端也无法一次接收,我必须研究其他可行的方式来传递这些资料
分批存取 Database
由于不能对 Table 直接 Select 100 万笔,所以势必要分批提供,这里我将 Timestamp 的栏位转 BIGINT 来供 filter 使用,并限制他每次 Select 的数量
每次用 Timestamp 的 int 数值,进 DB 搜寻后面 1,000 笔的资料
DB Select example:
SELECT TOP (1000)
teamId,
teamName,
teamTimestamp,
CONVERT(BIGINT, teamTimestamp) AS intTimestamp,
FROM team WITH (NOLOCK)
WHERE teamTimestamp >= CAST (@VersionKey AS timestamp)
ORDER BY timestamp
Timestamp 的资料型态是二进位的格式,当该项资料后续一旦有任何一个内容有异动,Timestamp 就会更新
如果有新增的项目,也会往后递增 Timestamp
所以当我用上一次 Select 的最后一笔 Timestamp + 1 去往后搜,即可取得 DB 后续有 add / update 的项目
需要为 Database 垫 cache 层
现在,资料请求的设计是:
请求端呼叫多次请求,每次取 1,000 笔,直到 count 为 0 停止请求
至此,就已经可以做到分批提供 100 万笔资料给 client 了
but …
由于资料是透过 API 提供出去,为了避免 Client 端频繁发送大量请求会对 DB 造成负担,我需要在 Service 和 DB 之间加一层 Redis Cache,以确保查询效率与系统稳定性。(不然会被 DBA 骂