प्रौद्योगिकी साझेदारी

cache - cache इत्यस्य उपयोगः २

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. सञ्चयस्य भङ्गः, प्रवेशः, हिमस्खलनः

1. संग्रहणप्रवेशः

एकं दत्तांशं पृच्छितुं निर्दिशति यत् सञ्चिकां न हिट् भवति, परन्तु दत्तांशकोशे एतादृशः अभिलेखः नास्ति, अस्माभिः अस्य प्रश्नस्य शून्यमूल्यं संग्रहे न लिखितम्, यस्य परिणामः भविष्यति अस्य अस्तित्वहीनस्य दत्तांशस्य प्रत्येकस्मिन् अनुरोधे भवद्भिः प्रश्नं कर्तुं भण्डारणस्तरं गन्तुं भवति, यत् संग्रहणस्य अर्थं नष्टं करोति ।

संशय:

आक्रमणं कर्तुं अस्तित्वहीनदत्तांशस्य उपयोगेन दत्तांशकोशे क्षणिकदबावः वर्धते, अन्ते च पतनम् अपि भविष्यति ।

उत्तरयति:

शून्यफलं संग्रहितं भवति तथा च अल्पः समाप्तिसमयः योजितः भवति ।

2. कैश हिमस्खलन

Cache avalanche: Cache avalanche इत्यस्य अर्थः अस्ति यत् यदा वयं cache सेट् कुर्मः तदा Key समानं समाप्तिसमयं स्वीकुर्वति, येन cache एकस्मिन् निश्चिते क्षणे अमान्यं भवति, सर्वे अनुरोधाः DB कृते अग्रे प्रेषिताः भवन्ति, तथा च DB तत्क्षणिकदबावस्य हिमस्खलनस्य च अधीनं भवति

समाधानम् : मूलसमाप्तिसमये यादृच्छिकं मूल्यं योजयन्तु, यथा यादृच्छिकरूपेण १-५ निमेषाः, येन प्रत्येकस्य संग्रहीतस्य समाप्तिसमयस्य पुनरावृत्तिदरः न्यूनीभवति, येन सामूहिकविफलताघटनानां कारणं कठिनं भवति

3. संग्रहविच्छेदः

संग्रहविच्छेदः : १.

  • समाप्तिसमयनिर्धारितस्य केषाञ्चन कीलानां कृते यदि एतानि कीलानि कतिपयेषु बिन्दुषु अतीव समवर्तीरूपेण अभिगन्तुं शक्यन्ते तर्हि अतीव "उष्णः" दत्तांशः अस्ति ।
  • यदि एतत् हॉटस्पॉट् कुञ्जी एकस्मिन् समये बहूनां अनुरोधानाम् आगमनात् पूर्वमेव समाप्तं भवति, तर्हि अस्य कीलस्य सर्वाणि दत्तांशप्रश्नाः db मध्ये पतन्ति, यत् cache breakdown इति कथ्यते

उत्तरयति:

ताल

बृहत् समवर्ती परिमाणं केवलं एकस्य जाँचं कर्तुं शक्नोति, अन्ये च प्रतीक्षन्ते, तालं मुक्तं भवति, अन्ये च तालं अधिगच्छति, भ्रमन्ति, प्रथमं cache परीक्षन्ते, ततः दत्तांशः भविष्यति, db - मध्ये न गत्वा

2. समस्यायाः समाधानं कुरुत

प्रथमं कैश-प्रवेशं हिमस्खलनं च समाधानं कुर्वन्तु

  1. private static final String CATALOG_JSON="CATALOG_JSON";
  2. @Override
  3. public Map<String, List<Catelog2Vo>> getCatalogJson() {
  4. /**
  5. * 空结果缓存:解决缓存穿透
  6. * 设置过期时间(加随机值) 缓存雪崩
  7. * 加锁 解决缓存击穿
  8. */
  9. Object result = redisTemplate.opsForValue().get(CATALOG_JSON);
  10. if(result!=null){
  11. return (Map<String, List<Catelog2Vo>>) result;
  12. }
  13. Map<String, List<Catelog2Vo>> map = getCatalogJsonFromDB();
  14. if (map==null){
  15. /**
  16. * 解决缓存穿透
  17. */
  18. map=new HashMap<>();
  19. }
  20. redisTemplate.opsForValue().set(CATALOG_JSON,map, Duration.ofDays(1));
  21. return map;
  22. }

कैश-विच्छेदस्य समाधानं कुर्वन्तु

1. समाधानार्थं स्थानीयतालस्य उपयोगं कुर्वन्तु

springboot container ऑब्जेक्ट् पूर्वनिर्धारितरूपेण singleton मोड् मध्ये अस्ति, अतः समानं ऑब्जेक्ट् समन्वयितुं लॉक् कर्तुं च शक्यते यदा द्वयात्मकं डिटेक्शन् मोड् उपयुज्यते तदा तत् समवर्तीरूपेण निष्पादयितुं शक्यते ।

  1. public synchronized Map<String, List<Catelog2Vo>> getCatalogJsonFromDB() {
  2. Object result = redisTemplate.opsForValue().get(CATALOG_JSON);
  3. if (result != null) {
  4. return (Map<String, List<Catelog2Vo>>) result;
  5. }
  6. //1.查出所有1级分类
  7. List<CategoryEntity> selectList = baseMapper.selectList(null);
  8. /**
  9. * 将数据库的多次查询变成一次
  10. */
  11. //2. 封装数据
  12. List<CategoryEntity> level1Category = selectList.stream().filter(s -> s.getParentCid().equals(0L)).collect(Collectors.toList());
  13. Map<String, List<Catelog2Vo>> map = level1Category.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {
  14. //1.每一个的一级分类,查到1级分类的所有二级分类
  15. List<CategoryEntity> categoryEntities = selectList.stream().filter(s -> s.getParentCid().equals(v.getCatId())).collect(Collectors.toList());
  16. List<Catelog2Vo> catelog2VoList = categoryEntities.stream().map(c -> {
  17. Catelog2Vo catelog2Vo = new Catelog2Vo();
  18. catelog2Vo.setId(c.getCatId().toString());
  19. catelog2Vo.setName(c.getName());
  20. catelog2Vo.setCatalog1Id(v.getCatId().toString());
  21. List<CategoryEntity> categoryEntities1 = selectList.stream().filter(s -> s.getParentCid().equals(c.getCatId())).collect(Collectors.toList());
  22. List<Catelog2Vo.Catelog3Vo> collect = categoryEntities1.stream().map(c3 -> {
  23. Catelog2Vo.Catelog3Vo catelog3Vo = new Catelog2Vo.Catelog3Vo();
  24. catelog3Vo.setId(c3.getCatId().toString());
  25. catelog3Vo.setName(c3.getName());
  26. catelog3Vo.setCatalog2Id(c.getCatId().toString());
  27. return catelog3Vo;
  28. }).collect(Collectors.toList());
  29. catelog2Vo.setCatalog3List(collect);
  30. return catelog2Vo;
  31. }).collect(Collectors.toList());
  32. return catelog2VoList;
  33. }));
  34. return map;
  35. }
  1. public Map<String, List<Catelog2Vo>> getCatalogJson() {
  2. /**
  3. * 空结果缓存:解决缓存穿透
  4. * 设置过期时间(加随机值) 缓存雪崩
  5. * 加锁 解决缓存击穿
  6. */
  7. Object result = redisTemplate.opsForValue().get(CATALOG_JSON);
  8. if (result != null) {
  9. return (Map<String, List<Catelog2Vo>>) result;
  10. }
  11. Map<String, List<Catelog2Vo>> map = getCatalogJsonFromDB();
  12. if (map == null) {
  13. /**
  14. * 解决缓存穿透
  15. */
  16. map = new HashMap<>();
  17. }
  18. redisTemplate.opsForValue().set(CATALOG_JSON, map, Duration.ofDays(1));
  19. return map;
  20. }

उपर्युक्तसङ्केतस्य तर्कस्य समस्याः अद्यापि भविष्यन्ति तथा च दत्तांशः नास्ति, अतः पुनः दत्तांशकोशस्य जाँचं करिष्यति दत्तांशकोशस्य जाँचार्थं केवलं एकः Thread भविष्यति इति गारण्टी नास्ति

सम्यक् उपाय

  1. public synchronized Map<String, List<Catelog2Vo>> getCatalogJsonFromDB() {
  2. Object result = redisTemplate.opsForValue().get(CATALOG_JSON);
  3. if (result != null) {
  4. return (Map<String, List<Catelog2Vo>>) result;
  5. }
  6. //1.查出所有1级分类
  7. List<CategoryEntity> selectList = baseMapper.selectList(null);
  8. /**
  9. * 将数据库的多次查询变成一次
  10. */
  11. //2. 封装数据
  12. List<CategoryEntity> level1Category = selectList.stream().filter(s -> s.getParentCid().equals(0L)).collect(Collectors.toList());
  13. Map<String, List<Catelog2Vo>> map = level1Category.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {
  14. //1.每一个的一级分类,查到1级分类的所有二级分类
  15. List<CategoryEntity> categoryEntities = selectList.stream().filter(s -> s.getParentCid().equals(v.getCatId())).collect(Collectors.toList());
  16. List<Catelog2Vo> catelog2VoList = categoryEntities.stream().map(c -> {
  17. Catelog2Vo catelog2Vo = new Catelog2Vo();
  18. catelog2Vo.setId(c.getCatId().toString());
  19. catelog2Vo.setName(c.getName());
  20. catelog2Vo.setCatalog1Id(v.getCatId().toString());
  21. List<CategoryEntity> categoryEntities1 = selectList.stream().filter(s -> s.getParentCid().equals(c.getCatId())).collect(Collectors.toList());
  22. List<Catelog2Vo.Catelog3Vo> collect = categoryEntities1.stream().map(c3 -> {
  23. Catelog2Vo.Catelog3Vo catelog3Vo = new Catelog2Vo.Catelog3Vo();
  24. catelog3Vo.setId(c3.getCatId().toString());
  25. catelog3Vo.setName(c3.getName());
  26. catelog3Vo.setCatalog2Id(c.getCatId().toString());
  27. return catelog3Vo;
  28. }).collect(Collectors.toList());
  29. catelog2Vo.setCatalog3List(collect);
  30. return catelog2Vo;
  31. }).collect(Collectors.toList());
  32. return catelog2VoList;
  33. }));
  34. if (map == null) {
  35. /**
  36. * 解决缓存穿透
  37. */
  38. map = new HashMap<>();
  39. }
  40. redisTemplate.opsForValue().set(CATALOG_JSON, map, Duration.ofDays(1));
  41. return map;
  42. }

कैशे मध्ये रक्षणस्य कार्यं समन्वयनसङ्केतखण्डे स्थापयन्तु

  1. @Override
  2. public Map<String, List<Catelog2Vo>> getCatalogJson() {
  3. /**
  4. * 空结果缓存:解决缓存穿透
  5. * 设置过期时间(加随机值) 缓存雪崩
  6. * 加锁 解决缓存击穿
  7. */
  8. Object result = redisTemplate.opsForValue().get(CATALOG_JSON);
  9. if (result != null) {
  10. return (Map<String, List<Catelog2Vo>>) result;
  11. }
  12. Map<String, List<Catelog2Vo>> map = getCatalogJsonFromDB();
  13. return map;
  14. }

 

 

स्थानीयतालाः केवलं वर्तमानप्रक्रियायाः तालान् स्थापयितुं शक्नुवन्ति, अतः अस्माकं वितरिततालानां आवश्यकता वर्तते

3. वितरितवातावरणेषु स्थानीयतालानां समस्याः

अर्थात् प्रत्येकं तालं केवलं वर्तमानप्रक्रियाम् एव ताडयितुं शक्नोति, अर्थात् प्रत्येकं सेवा दत्तांशकोशं परीक्षयिष्यति ।