内存大小:(初始化的位数量 / 误报率)KB。
ts// 内存大小占用:100000(初始化的位数量)/0.001(误报率) = 100KB
BloomFilter.create(100000, 0.001);//占用内存:100KB
110情况1:如果输入的数据非常有规律(例如:自增的 ID
10001, 10002, 10003,或者具有相同前缀的字符串
user_group_1, user_group_2)。
10情况2:如果输入的数据本身就是一堆毫无规律的随机噪声、UUID、或者是经过高强度加密的哈希值。
11tsimport { Injectable, OnModuleInit } from '@nestjs/common';
import { BloomFilter } from 'bloom-filters';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { OrderEntity } from '@/module/entity/order.entity';
@Injectable()
export class BloomService implements OnModuleInit {
private bloomFilter: BloomFilter;
constructor(
@InjectRepository(OrderEntity)
private orderRepo: Repository<OrderEntity>,
) {
// 初始化订单是否存在的 bloom 过滤器,内存大小占用:100000/0.001 = 100KB
this.bloomFilter = BloomFilter.create(100000, 0.001);
}
// 将数据放到布隆过滤器
async onModuleInit() {
const orders = await this.orderRepo.find({ select: ['id'] });
orders.forEach((order) => {
this.bloomFilter.add(order.id as string);
});
}
// 擦除并重建布隆过滤器
refactorBloom() {
this.bloomFilter = BloomFilter.create(100000, 0.001);
}
// 向过滤器新增数据
add(orderId: string) {
this.bloomFilter.add(orderId);
}
// 判断数据是否存在
exists(orderId: string): boolean {
return this.bloomFilter.has(orderId);
}
}
tsimport { writeFileSync, existsSync, readFileSync } from 'node:fs';
import { Repository } from 'typeorm';
import { CuckooFilter } from 'bloom-filters';
import { InjectRepository } from '@nestjs/typeorm';
import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { OrderEntity } from '@/module/entity/order.entity';
import { CUCKOO_FILE_PATH } from '@/constants/order';
@Injectable()
export class CuckooService implements OnModuleInit, OnModuleDestroy {
private CuckooFilter: CuckooFilter;
constructor(
@InjectRepository(OrderEntity)
private orderRepo: Repository<OrderEntity>,
) {}
async onModuleInit() {
// 支持将数据存储本地,服务器启动时,先加载本地数据
if (existsSync(CUCKOO_FILE_PATH)) {
const data = JSON.parse(readFileSync(CUCKOO_FILE_PATH, 'utf8')) as JSON;
this.CuckooFilter = CuckooFilter.fromJSON(data);
} else {
// 一样内存占用大小计算方式
this.CuckooFilter = CuckooFilter.create(100000, 0.001);
await this.refactorData();
}
}
onModuleDestroy() {
// 保存数据至本地
this.saveDisk();
}
// 将数据存放到布谷鸟过滤器
async refactorData() {
const orders = await this.orderRepo.find({ select: ['id'] });
orders.forEach((order) => {
this.CuckooFilter.add(order.id as string);
});
}
// 添加数据
add(orderId: string) {
this.CuckooFilter.add(orderId);
}
// 判断数据是否存在
exists(orderId: string): boolean {
return this.CuckooFilter.has(orderId);
}
// 删除数据
del(orderId: string) {
return this.CuckooFilter.remove(orderId);
}
// 将数据持久化到本地
saveDisk() {
const data = JSON.stringify(this.CuckooFilter.saveAsJSON());
writeFileSync(CUCKOO_FILE_PATH, data);
}
}