golang实现的redis布隆过滤器_高并发13-redis+布隆过滤器实现秒杀功能

- 功能核心点

* 经典互联网商品抢购秒杀功能

- 功能api

* 商品秒杀接口

- 数据落地存储方案

* 通过分布式redis减库存

* DB存最终订单信息数据

- api性能调优

* 性能瓶颈在高并发秒杀

* 技术难题在于超卖问题

秒杀系统功能步骤梳理

- 利用 Redis 缓存incr拦截流量

- 首先通过数据控制模块,提前将秒杀商品缓存到读写分离 Redis,并设置秒杀开始标记如下:

"skuId_start": 0 //开始标记1表示秒杀开始

"skuId_count": 10000 //总数

"skuId_access": 12000 //接受抢购数(接受最大抢购数=1.2*商品总数)

- 秒杀开始前,服务集群读取 skuId_start为 0,直接返回未开始。

- 服务时间不一致可能导致流量倾斜

- 数据控制模块将 skuId_start 改为1,标志秒杀开始。

- 当接受下单数达到 sku_count*1.2 后,继续拦截所有请求,商品剩余数量为 0

- 利用Redis缓存加速库存扣量

"skuId_booked": 10000 //总数0开始10000 通过incr扣减库存,返回抢购成功

- 将用户订单数据写入mq

- 监听mq入库

秒杀系统功能api实战(上)

** 后端秒杀网关流量拦截层功能开发 **

- 先判断秒杀是否已经开始

* 初始化时将key:skuId_start_1 value:0_1554046102存入数据库中

- 利用 Redis 缓存incr拦截流量

- 缓存拦截流量代码编写

- 用incr方法原子加

- 通过原子加判断当前skuId_access是否达到最大值

- 思考:是否需要保证获取到值的时候和incr值两个命令的原子性

* 保证原子性的方式,采用lua脚本

* 采用lua脚本方式保证原子性带来缺点,性能有所下降

* 不保证原子性缺点,放入请求量可能大于skuId_access

秒杀系统功能api实战(中)

** 后端秒杀信息校验层功能开发布隆过滤器实现重复购买拦截 **

- 订单信息校验层

* 校验当前用户是否已经买过这个商品

- 需要存储用户的uid

- 存数据库效率太低

- 存Redis value方式数据太大

- 存布隆过滤器性能高且数据量小

- 校验完通过直接返回抢购成功

秒杀系统功能api实战(下)

** 后端秒杀信息校验层功能开发lua脚本实现库存扣除**

- 库存扣除成功,获取当前最新库存

- 如果库存大于0,即马上进行库存扣除,并且访问抢购成功给用户

- 考虑原子性问题

* 保证原子性的方式,采用lua脚本

* 采用lua脚本方式保证原子性带来缺点,性能有所下降

* 不保证原子性缺点,放入请求量可能大于预期值

* 当前扣除库存场景必须保证原子性,否则会导致超卖

- 返回抢购结果

* 抢购成功

* 库存没了 ,抢购失败

初始化库存数据:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是用Golang实现布隆过滤器的示例代码: ```go package main import ( "bufio" "fmt" "hash/fnv" "os" ) type BloomFilter struct { bitset []bool k uint64 } func NewBloomFilter(m uint64, k uint64) *BloomFilter { return &BloomFilter{make([]bool, m), k} } func (bf *BloomFilter) Add(s string) { for i := uint64(0); i < bf.k; i++ { h := fnv.New64a() h.Write([]byte(s)) index := h.Sum64() % uint64(len(bf.bitset)) bf.bitset[index] = true } } func (bf *BloomFilter) Contains(s string) bool { for i := uint64(0); i < bf.k; i++ { h := fnv.New64a() h.Write([]byte(s)) index := h.Sum64() % uint64(len(bf.bitset)) if !bf.bitset[index] { return false } } return true } func main() { bf := NewBloomFilter(10000, 3) // Add some strings to the Bloom filter bf.Add("apple") bf.Add("banana") bf.Add("orange") // Check if some strings are in the Bloom filter fmt.Println(bf.Contains("apple")) // true fmt.Println(bf.Contains("banana")) // true fmt.Println(bf.Contains("orange")) // true fmt.Println(bf.Contains("grape")) // false fmt.Println(bf.Contains("peach")) // false fmt.Println(bf.Contains("pineapple")) // false // Read some strings from a file and check if they are in the Bloom filter file, _ := os.Open("words.txt") defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { word := scanner.Text() if bf.Contains(word) { fmt.Printf("%s may be in the set\n", word) } } } ``` 以上是一个简单的布隆过滤器实现,它使用了FNV-1a哈希算法来计算字符串的哈希值,并将哈希值映射到一个布隆过滤器的位数组中,如果位数组中的所有位都被置位了,那么就认为这个字符串可能在集合中。注意,这个实现中的位数组大小是固定的,如果集合中的元素数量超过了位数组的大小,那么误判率就会增加。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值