跳到主内容

评估

Prisma Accelerate 通过高级连接池和全球边缘缓存来优化数据库交互。其连接池器在 16 个区域可用,并帮助应用程序根据需求进行负载均衡和扩展数据库请求。

考虑到以上信息,我们建议在高负载下评估 Accelerate 的性能表现。

Accelerate 的连接池如何在负载下优化性能

Prisma Accelerate 采用动态、无服务器的连接池基础设施。当发出请求时,会在配置 Prisma Accelerate 时分配的区域中,为项目快速配置一个连接池。此连接池保持活跃,在重用已建立的数据库连接的同时,服务许多额外的请求。连接池会在一段时间不活动后断开连接,因此使用持续的流量流来评估 Prisma Accelerate 非常重要。

主要优势

  • 优化的查询性能:无服务器连接池器会适应查询负载,确保在高峰需求期间高效管理数据库连接。

    Prisma Accelerate 的连接池器无法提升数据库中查询的性能。在查询性能存在问题的场景下,我们建议优化 Prisma 查询、应用索引或利用 Accelerate 的边缘缓存。

  • 最大化连接复用:执行持续大量的查询有助于保持 Accelerate 连接池器的活跃实例。这会增加连接复用,确保后续查询的更快响应时间。

通过理解和利用此机制,您可以确保您的数据库查询在大规模下保持一致且高效的性能。

评估 Prisma Accelerate 连接池性能

您将在下方找到一个如何使用示例模型评估 Prisma Accelerate 的示例

model Notes {
id Int @id @default(autoincrement())
title String
createdAt DateTime @default(now())
updatedAt DateTime? @updatedAt
}
import { PrismaClient } from '@prisma/client'
import { withAccelerate } from '@prisma/extension-accelerate'

const prisma = new PrismaClient().$extends(withAccelerate())

function calculateStatistics(numbers: number[]): {
average: number
p50: number
p75: number
p99: number
} {
if (numbers.length === 0) {
throw new Error('The input array is empty.')
}

// Sort the array in ascending order
numbers.sort((a, b) => a - b)

const sum = numbers.reduce((acc, num) => acc + num, 0)
const count = numbers.length

const average = sum / count
const p50 = getPercentile(numbers, 50)
const p75 = getPercentile(numbers, 75)
const p99 = getPercentile(numbers, 99)

return { average, p50, p75, p99 }
}

function getPercentile(numbers: number[], percentile: number): number {
if (percentile <= 0 || percentile >= 100) {
throw new Error('Percentile must be between 0 and 100.')
}

const index = (percentile / 100) * (numbers.length - 1)
if (Number.isInteger(index)) {
// If the index is an integer, return the corresponding value
return numbers[index]
} else {
// If the index is not an integer, interpolate between two adjacent values
const lowerIndex = Math.floor(index)
const upperIndex = Math.ceil(index)
const lowerValue = numbers[lowerIndex]
const upperValue = numbers[upperIndex]
const interpolationFactor = index - lowerIndex
return lowerValue + (upperValue - lowerValue) * interpolationFactor
}
}

async function main() {
const timings = []

// fire a query before going to the loop
await prisma.notes.findMany({
take: 20,
})

// we recommend evaluationg Prisma Accelerate with a large loop
const LOOP_LENGTH = 10000

for (let i = 0; i < LOOP_LENGTH; i++) {
const start = Date.now()
await prisma.notes.findMany({
take: 20,
})

timings.push(Date.now() - start)
}

const statistics = calculateStatistics(timings)
console.log('Average:', statistics.average)
console.log('P50:', statistics.p50)
console.log('P75:', statistics.p75)
console.log('P99:', statistics.p99)
}

main()
.then(async () => {
await prisma.$disconnect()
})
.catch((e) => {
await prisma.$disconnect()
process.exit(1)
})

评估 Prisma Accelerate 缓存性能

Prisma Accelerate 的边缘缓存也针对高查询量进行了优化。缓存会自动优化重复查询。因此,缓存命中率会随着查询频率的增加而提高。将查询结果添加到缓存也是非阻塞的,因此短时间的查询突增可能无法充分利用缓存,而需要持续负载才能发挥作用。

要评估 Accelerate 的边缘缓存,您可以修改上述脚本,如下所示

import { PrismaClient } from '@prisma/client'
import { withAccelerate } from '@prisma/extension-accelerate'

const prisma = new PrismaClient().$extends(withAccelerate())

function calculateStatistics(numbers: number[]): {
average: number
p50: number
p75: number
p99: number
} {
if (numbers.length === 0) {
throw new Error('The input array is empty.')
}

// Sort the array in ascending order
numbers.sort((a, b) => a - b)

const sum = numbers.reduce((acc, num) => acc + num, 0)
const count = numbers.length

const average = sum / count
const p50 = getPercentile(numbers, 50)
const p75 = getPercentile(numbers, 75)
const p99 = getPercentile(numbers, 99)

return { average, p50, p75, p99 }
}

function getPercentile(numbers: number[], percentile: number): number {
if (percentile <= 0 || percentile >= 100) {
throw new Error('Percentile must be between 0 and 100.')
}

const index = (percentile / 100) * (numbers.length - 1)
if (Number.isInteger(index)) {
// If the index is an integer, return the corresponding value
return numbers[index]
} else {
// If the index is not an integer, interpolate between two adjacent values
const lowerIndex = Math.floor(index)
const upperIndex = Math.ceil(index)
const lowerValue = numbers[lowerIndex]
const upperValue = numbers[upperIndex]
const interpolationFactor = index - lowerIndex
return lowerValue + (upperValue - lowerValue) * interpolationFactor
}
}

async function main() {
const timings = []

// fire a query before going to the loop
await prisma.notes.findMany({
take: 20,
cacheStrategy: {
ttl: 30,
},
})

// we recommend evaluating Prisma Accelerate with a large loop
const LOOP_LENGTH = 10000

for (let i = 0; i < LOOP_LENGTH; i++) {
const start = Date.now()
await prisma.notes.findMany({
take: 20,
cacheStrategy: {
ttl: 30,
},
})

timings.push(Date.now() - start)
}

const statistics = calculateStatistics(timings)
console.log('Average:', statistics.average)
console.log('P50:', statistics.p50)
console.log('P75:', statistics.p75)
console.log('P99:', statistics.p99)
}

main()
.then(async () => {
await prisma.$disconnect()
})
.catch((e) => {
await prisma.$disconnect()
process.exit(1)
})
© . All rights reserved.