成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

從SpringBoot構(gòu)建十萬(wàn)博文聊聊緩存穿透,并發(fā)量過(guò)大該如何抗壓?

存儲(chǔ) 存儲(chǔ)軟件
在博客系統(tǒng)中,為了提升響應(yīng)速度,加入了 Redis 緩存,把文章主鍵 ID 作為 key 值去緩存查詢,如果不存在對(duì)應(yīng)的 value,就去數(shù)據(jù)庫(kù)中查找 。這個(gè)時(shí)候,如果請(qǐng)求的并發(fā)量很大,就會(huì)對(duì)后端的數(shù)據(jù)庫(kù)服務(wù)造成很大的壓力。

 前言

在博客系統(tǒng)中,為了提升響應(yīng)速度,加入了 Redis 緩存,把文章主鍵 ID 作為 key 值去緩存查詢,如果不存在對(duì)應(yīng)的 value,就去數(shù)據(jù)庫(kù)中查找 。這個(gè)時(shí)候,如果請(qǐng)求的并發(fā)量很大,就會(huì)對(duì)后端的數(shù)據(jù)庫(kù)服務(wù)造成很大的壓力。

[[313074]]

造成原因

  • 業(yè)務(wù)自身代碼或數(shù)據(jù)出現(xiàn)問(wèn)題
  • 惡意攻擊、爬蟲(chóng)造成大量空的命中,會(huì)對(duì)數(shù)據(jù)庫(kù)造成很大壓力

案例分析

由于文章的地址是這樣子的:

https://blog.52itstyle.top/49.html

大家很容易猜出,是不是還有 50、51、52 甚至是十萬(wàn)+?如果是正兒八經(jīng)的爬蟲(chóng),可能會(huì)讀取你的總頁(yè)數(shù)。但是有些不正經(jīng)的爬蟲(chóng)或者人,還真以為你有十萬(wàn)+博文,然后就寫(xiě)了這么一個(gè)腳本。

  1. for num in range(1,1000000): 
  2.  //爬死你,開(kāi)100個(gè)線程 

解決方案

設(shè)置布隆過(guò)濾器,預(yù)先將所有文章的主鍵 ID 哈希到一個(gè)足夠大的 BitMap 中,每次請(qǐng)求都會(huì)經(jīng)過(guò) BitMap 的攔截,如果 Key 不存在,直接返回異常。這樣就避免了對(duì) Redis 緩存以及底層數(shù)據(jù)庫(kù)的查詢壓力。

這里我們使用谷歌開(kāi)源的第三方工具類(lèi)來(lái)實(shí)現(xiàn):

  1. <dependency> 
  2.  <groupId>com.google.guava</groupId> 
  3.  <artifactId>guava</artifactId> 
  4.  <version>25.1-jre</version> 
  5. </dependency> 

編寫(xiě)布隆過(guò)濾器:

  1. /** 
  2.  * 布隆緩存過(guò)濾器 
  3.  */ 
  4. @Component 
  5. public class BloomCacheFilter { 
  6.  public static BloomFilter<Integer> bloomFilter = null
  7.  @Autowired 
  8.  private DynamicQuery dynamicQuery; 
  9.  /** 
  10.  * 初始化 
  11.  */ 
  12.  @PostConstruct 
  13.  public void init(){ 
  14.  String nativeSql = "SELECT id FROM blog"
  15.  List<Object> list = dynamicQuery.query(nativeSql,new Object[]{}); 
  16.  bloomFilter = BloomFilter.create(Funnels.integerFunnel(), list.size()); 
  17.  list.forEach(blog ->bloomFilter.put(Integer.parseInt(blog.toString()))); 
  18.  } 
  19.  /** 
  20.  * 判斷key是否存在 
  21.  * @param key 
  22.  * @return 
  23.  */ 
  24.  public static boolean mightContain(long key){ 
  25.  return bloomFilter.mightContain((int)key); 
  26.  } 

然后,每一次查詢之前做一次 Key 值校驗(yàn):

  1. /** 
  2.  * 博文 
  3.  */ 
  4. @RequestMapping("{id}.shtml"
  5. public String page(@PathVariable("id") Long id, ModelMap model) { 
  6.  if(BloomCacheFilter.mightContain(id)){ 
  7.  Blog blog = blogService.getById(id); 
  8.  model.addAttribute("blog",blog); 
  9.  return "article"
  10.  }else
  11.  return "error"
  12.  } 

效率

那么,在數(shù)據(jù)量很大的情況下,效率如何呢?我們來(lái)做個(gè)實(shí)驗(yàn),以 100W 為基數(shù)。

  1. public static void main(String[] args) { 
  2.  int capacity = 1000000; 
  3.  int key = 6666; 
  4.  BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), capacity); 
  5.  for (int i = 0; i < capacity; i++) { 
  6.  bloomFilter.put(i); 
  7.  } 
  8.  /**返回計(jì)算機(jī)最精確的時(shí)間,單位納妙 */ 
  9.  long start = System.nanoTime(); 
  10.  if (bloomFilter.mightContain(key)) { 
  11.  System.out.println("成功過(guò)濾到" + key); 
  12.  } 
  13.  long end = System.nanoTime(); 
  14.  System.out.println("布隆過(guò)濾器消耗時(shí)間:" + (end - start)); 

布隆過(guò)濾器消耗時(shí)間:281299,約等于 0.28 毫秒,匹配速度是不是很快?

錯(cuò)判率

萬(wàn)事萬(wàn)物都有所均衡,既然效率如此之高,肯定其它方面定有所犧牲,通過(guò)測(cè)試我們發(fā)現(xiàn),過(guò)濾器有 3% 的錯(cuò)判率,也就是說(shuō),本來(lái)沒(méi)有的文章,有可能通過(guò)校驗(yàn)被訪問(wèn)到,然后報(bào)錯(cuò)!

  1. public static void main(String[] args) { 
  2.  int capacity = 1000000; 
  3.  BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), capacity); 
  4.  for (int i = 0; i < capacity; i++) { 
  5.  bloomFilter.put(i); 
  6.  } 
  7.  int sum = 0; 
  8.  for (int i = capacity + 20000; i < capacity + 30000; i++) { 
  9.  if (bloomFilter.mightContain(i)) { 
  10.  sum ++; 
  11.  } 
  12.  } 
  13.  //0.03 
  14.  DecimalFormat df=new DecimalFormat("0.00");//設(shè)置保留位數(shù) 
  15.  System.out.println("錯(cuò)判率為:" + df.format((float)sum/10000)); 

通過(guò)源碼閱讀,發(fā)現(xiàn) 3% 的錯(cuò)判率是系統(tǒng)寫(xiě)死的。

  1. public static <T> BloomFilter<T> create(Funnel<? super T> funnel, long expectedInsertions) { 
  2.  return create(funnel, expectedInsertions, 0.03D); 

當(dāng)然我們也可以通過(guò)傳參,降低錯(cuò)判率。測(cè)試了一下,查詢速度稍微有一丟丟降低,但也只是零點(diǎn)幾毫秒級(jí)的而已。

  1. BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), capacity,0.01); 

那么如何做到零錯(cuò)判率呢?答案是不可能的,布隆過(guò)濾器,錯(cuò)判率必須大于零。為了保證文章 100% 的訪問(wèn)率,正常情況下,我們可以關(guān)閉布隆校驗(yàn),只有才突發(fā)情況下開(kāi)啟。比如,可以通過(guò)阿里的動(dòng)態(tài)參數(shù)配置 Nacos 實(shí)現(xiàn)。

  1. @NacosValue(value = "${bloomCache:false}", autoRefreshed = true
  2. private boolean bloomCache; 
  3. //省略部分代碼 
  4. if(bloomCache||BloomCacheFilter.mightContain(id)){ 
  5.  Blog blog = blogService.getById(id); 
  6.  model.addAttribute("blog",blog); 
  7.  return "article"
  8. }else
  9.  return "error"

小結(jié)

緩存穿透大多數(shù)情況下都是惡意攻擊導(dǎo)致的空命中率。雖然十萬(wàn)博客還沒(méi)有被百度收錄,每天也就寥寥的幾十個(gè)IP,但是夢(mèng)想還是有的,萬(wàn)一實(shí)現(xiàn)了呢?所以,還是要做好準(zhǔn)備的!

 

責(zé)任編輯:武曉燕 來(lái)源: 今日頭條
相關(guān)推薦

2024-03-27 14:39:48

MySQL數(shù)據(jù)庫(kù)分庫(kù)分表

2017-12-27 12:01:39

2018-12-13 12:43:07

Redis緩存穿透

2016-11-28 09:00:10

瀏覽器瀏覽器緩存服務(wù)端

2023-07-19 07:51:43

Redis緩存高可用

2009-11-25 13:38:20

IIS并發(fā)數(shù)

2019-07-21 09:17:11

數(shù)據(jù)緩存架構(gòu)

2024-06-05 10:07:00

限流微服務(wù)算法

2022-06-17 07:49:14

緩存LRU

2025-05-28 02:25:00

高并發(fā)緩存穿透雪崩

2023-03-10 13:33:00

緩存穿透緩存擊穿緩存雪崩

2019-10-12 14:19:05

Redis數(shù)據(jù)庫(kù)緩存

2021-09-06 11:58:24

Python腳本Jmeter

2022-06-12 06:45:26

高并發(fā)防重

2023-03-07 08:17:19

Postgresql數(shù)據(jù)庫(kù)優(yōu)化

2019-11-05 14:24:31

緩存雪崩框架

2023-07-03 09:59:00

并發(fā)編程并發(fā)容器

2018-06-11 11:12:09

秒殺限流分布式

2018-07-19 09:43:41

MemcacheRedis緩存

2018-06-19 09:35:51

分布式系統(tǒng)限流
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 欧美美女被c | 一区影院| 国产精品成人一区二区三区夜夜夜 | 久久综合九色综合欧美狠狠 | 欧产日产国产精品视频 | 欧美一级在线 | 91九色在线观看 | 日本视频免费观看 | www.久久| 一区二视频 | 欧美色综合天天久久综合精品 | 在线一区二区三区 | 日韩精品一区二区三区视频播放 | 日本成人在线播放 | 久久涩涩| 国产91久久精品一区二区 | 日日夜夜操天天干 | 久久久黑人 | 五月综合久久 | 欧美亚洲视频 | 亚洲国产精品一区二区第一页 | 你懂的av| 99亚洲精品 | 伊人网91| 国产福利观看 | 日本三级全黄三级三级三级口周 | 久久精品小视频 | 麻豆精品国产91久久久久久 | 亚洲资源在线 | 久草色播| 欧美激情久久久 | 婷婷色国产偷v国产偷v小说 | 在线观看视频91 | 国产一区二区三区不卡av | 日韩av在线中文字幕 | 欧美久久久久久 | 亚洲精品视频免费观看 | 色婷婷久久 | 亚洲精品国产一区 | 欧美日韩网站 | 国产精品亚洲成在人线 |