Redis中6種緩存更新策略

Redis作為一款高性能的內存數據庫,已經成為緩存層的首選解決方案。然而,使用緩存時最大的挑戰在于保證緩存數據與底層數據源的一致性。緩存更新策略直接影響系統的性能、可靠性和數據一致性,選擇合適的策略至關重要。

本文將介紹Redis中6種緩存更新策略。

策略一:Cache-Aside(旁路緩存)策略

工作原理

Cache-Aside是最常用的緩存模式,由應用層負責緩存和數據庫的交互邏輯:

  1. 讀取數據:先查詢緩存,命中則直接返回;未命中則查詢數據庫,將結果寫入緩存并返回
  2. 更新數據:先更新數據庫,再刪除緩存(或更新緩存)

代碼示例

@Service
public class UserServiceCacheAside {@Autowiredprivate RedisTemplate<String, User> redisTemplate;@Autowiredprivate UserRepository userRepository;private static final String CACHE_KEY_PREFIX = "user:";private static final long CACHE_EXPIRATION = 30; // 緩存過期時間(分鐘)public User getUserById(Long userId) {String cacheKey = CACHE_KEY_PREFIX + userId;// 1. 查詢緩存User user = redisTemplate.opsForValue().get(cacheKey);// 2. 緩存命中,直接返回if (user != null) {return user;}// 3. 緩存未命中,查詢數據庫user = userRepository.findById(userId).orElse(null);// 4. 將數據庫結果寫入緩存(設置過期時間)if (user != null) {redisTemplate.opsForValue().set(cacheKey, user, CACHE_EXPIRATION, TimeUnit.MINUTES);}return user;}public void updateUser(User user) {// 1. 先更新數據庫userRepository.save(user);// 2. 再刪除緩存String cacheKey = CACHE_KEY_PREFIX + user.getId();redisTemplate.delete(cacheKey);// 或者選擇更新緩存// redisTemplate.opsForValue().set(cacheKey, user, CACHE_EXPIRATION, TimeUnit.MINUTES);}
}

優缺點分析

優點

  • 實現簡單,控制靈活
  • 適合讀多寫少的業務場景
  • 只緩存必要的數據,節省內存空間

缺點

  • 首次訪問會有一定延遲(緩存未命中)
  • 存在并發問題:如果先刪除緩存后更新數據庫,可能導致數據不一致
  • 需要應用代碼維護緩存一致性,增加了開發復雜度

適用場景

  • 讀多寫少的業務場景
  • 對數據一致性要求不是特別高的應用
  • 分布式系統中需要靈活控制緩存策略的場景

策略二:Read-Through(讀穿透)策略

工作原理

Read-Through策略將緩存作為主要數據源的代理,由緩存層負責數據加載:

  1. 應用程序只與緩存層交互
  2. 當緩存未命中時,由緩存管理器負責從數據庫加載數據并存入緩存
  3. 應用程序無需關心緩存是否存在,緩存層自動處理加載邏輯

代碼示例

首先定義緩存加載器接口:

public interface CacheLoader<K, V> {V load(K key);
}

實現Read-Through緩存管理器:

@Component
public class ReadThroughCacheManager<K, V> {@Autowiredprivate RedisTemplate<String, V> redisTemplate;private final ConcurrentHashMap<String, CacheLoader<K, V>> loaders = new ConcurrentHashMap<>();public void registerLoader(String cachePrefix, CacheLoader<K, V> loader) {loaders.put(cachePrefix, loader);}public V get(String cachePrefix, K key, long expiration, TimeUnit timeUnit) {String cacheKey = cachePrefix + key;// 1. 查詢緩存V value = redisTemplate.opsForValue().get(cacheKey);// 2. 緩存命中,直接返回if (value != null) {return value;}// 3. 緩存未命中,通過加載器獲取數據CacheLoader<K, V> loader = loaders.get(cachePrefix);if (loader == null) {throw new IllegalStateException("No cache loader registered for prefix: " + cachePrefix);}// 使用加載器從數據源加載數據value = loader.load(key);// 4. 將加載的數據存入緩存if (value != null) {redisTemplate.opsForValue().set(cacheKey, value, expiration, timeUnit);}return value;}
}

使用示例:

@Service
public class UserServiceReadThrough {private static final String CACHE_PREFIX = "user:";private static final long CACHE_EXPIRATION = 30;@Autowiredprivate ReadThroughCacheManager<Long, User> cacheManager;@Autowiredprivate UserRepository userRepository;@PostConstructpublic void init() {// 注冊用戶數據加載器cacheManager.registerLoader(CACHE_PREFIX, this::loadUserFromDb);}private User loadUserFromDb(Long userId) {return userRepository.findById(userId).orElse(null);}public User getUserById(Long userId) {// 直接通過緩存管理器獲取數據,緩存邏輯由管理器處理return cacheManager.get(CACHE_PREFIX, userId, CACHE_EXPIRATION, TimeUnit.MINUTES);}
}

優缺點分析

優點

  • 封裝性好,應用代碼無需關心緩存邏輯
  • 集中處理緩存加載,減少冗余代碼
  • 適合只讀或讀多寫少的數據

缺點

  • 緩存未命中時引發數據庫請求,可能導致數據庫負載增加
  • 無法直接處理寫操作,需要與其他策略結合使用
  • 需要額外維護一個緩存管理層

適用場景

  • 讀操作頻繁的業務系統
  • 需要集中管理緩存加載邏輯的應用
  • 復雜的緩存預熱和加載場景

策略三:Write-Through(寫穿透)策略

工作原理

Write-Through策略由緩存層同步更新底層數據源:

  1. 應用程序更新數據時先寫入緩存
  2. 然后由緩存層負責同步寫入數據庫
  3. 只有當數據成功寫入數據庫后才視為更新成功

代碼示例

首先定義寫入接口:

public interface CacheWriter<K, V> {void write(K key, V value);
}

實現Write-Through緩存管理器:

@Component
public class WriteThroughCacheManager<K, V> {@Autowiredprivate RedisTemplate<String, V> redisTemplate;private final ConcurrentHashMap<String, CacheWriter<K, V>> writers = new ConcurrentHashMap<>();public void registerWriter(String cachePrefix, CacheWriter<K, V> writer) {writers.put(cachePrefix, writer);}public void put(String cachePrefix, K key, V value, long expiration, TimeUnit timeUnit) {String cacheKey = cachePrefix + key;// 1. 獲取對應的緩存寫入器CacheWriter<K, V> writer = writers.get(cachePrefix);if (writer == null) {throw new IllegalStateException("No cache writer registered for prefix: " + cachePrefix);}// 2. 同步寫入數據庫writer.write(key, value);// 3. 更新緩存redisTemplate.opsForValue().set(cacheKey, value, expiration, timeUnit);}
}

使用示例:

@Service
public class UserServiceWriteThrough {private static final String CACHE_PREFIX = "user:";private static final long CACHE_EXPIRATION = 30;@Autowiredprivate WriteThroughCacheManager<Long, User> cacheManager;@Autowiredprivate UserRepository userRepository;@PostConstructpublic void init() {// 注冊用戶數據寫入器cacheManager.registerWriter(CACHE_PREFIX, this::saveUserToDb);}private void saveUserToDb(Long userId, User user) {userRepository.save(user);}public void updateUser(User user) {// 通過緩存管理器更新數據,會同步更新數據庫和緩存cacheManager.put(CACHE_PREFIX, user.getId(), user, CACHE_EXPIRATION, TimeUnit.MINUTES);}
}

優缺點分析

優點

  • 保證數據庫與緩存的強一致性
  • 將緩存更新邏輯封裝在緩存層,簡化應用代碼
  • 讀取緩存時命中率高,無需回源到數據庫

缺點

  • 實時寫入數據庫增加了寫操作延遲
  • 增加系統復雜度,需要處理事務一致性
  • 對數據庫寫入壓力大的場景可能成為性能瓶頸

適用場景

  • 對數據一致性要求高的系統
  • 寫操作不是性能瓶頸的應用
  • 需要保證緩存與數據庫實時同步的場景

策略四:Write-Behind(寫回)策略

工作原理

Write-Behind策略將寫操作異步化處理:

  1. 應用程序更新數據時只更新緩存
  2. 緩存維護一個寫入隊列,將更新異步批量寫入數據庫
  3. 通過批量操作減輕數據庫壓力

代碼示例

實現異步寫入隊列和處理器:

@Component
public class WriteBehindCacheManager<K, V> {@Autowiredprivate RedisTemplate<String, V> redisTemplate;private final BlockingQueue<CacheUpdate<K, V>> updateQueue = new LinkedBlockingQueue<>();private final ConcurrentHashMap<String, CacheWriter<K, V>> writers = new ConcurrentHashMap<>();public void registerWriter(String cachePrefix, CacheWriter<K, V> writer) {writers.put(cachePrefix, writer);}@PostConstructpublic void init() {// 啟動異步寫入線程Thread writerThread = new Thread(this::processWriteBehindQueue);writerThread.setDaemon(true);writerThread.start();}public void put(String cachePrefix, K key, V value, long expiration, TimeUnit timeUnit) {String cacheKey = cachePrefix + key;// 1. 更新緩存redisTemplate.opsForValue().set(cacheKey, value, expiration, timeUnit);// 2. 將更新放入隊列,等待異步寫入數據庫updateQueue.offer(new CacheUpdate<>(cachePrefix, key, value));}private void processWriteBehindQueue() {List<CacheUpdate<K, V>> batch = new ArrayList<>(100);while (true) {try {// 獲取隊列中的更新,最多等待100msCacheUpdate<K, V> update = updateQueue.poll(100, TimeUnit.MILLISECONDS);if (update != null) {batch.add(update);}// 繼續收集隊列中可用的更新,最多收集100個或等待200msupdateQueue.drainTo(batch, 100 - batch.size());if (!batch.isEmpty()) {// 按緩存前綴分組批量處理Map<String, List<CacheUpdate<K, V>>> groupedUpdates = batch.stream().collect(Collectors.groupingBy(CacheUpdate::getCachePrefix));for (Map.Entry<String, List<CacheUpdate<K, V>>> entry : groupedUpdates.entrySet()) {String cachePrefix = entry.getKey();List<CacheUpdate<K, V>> updates = entry.getValue();CacheWriter<K, V> writer = writers.get(cachePrefix);if (writer != null) {// 批量寫入數據庫for (CacheUpdate<K, V> u : updates) {try {writer.write(u.getKey(), u.getValue());} catch (Exception e) {// 處理異常,可以重試或記錄日志log.error("Failed to write-behind for key {}: {}", u.getKey(), e.getMessage());}}}}batch.clear();}} catch (InterruptedException e) {Thread.currentThread().interrupt();break;} catch (Exception e) {log.error("Error in write-behind process", e);}}}@Data@AllArgsConstructorprivate static class CacheUpdate<K, V> {private String cachePrefix;private K key;private V value;}
}

使用示例:

@Service
public class UserServiceWriteBehind {private static final String CACHE_PREFIX = "user:";private static final long CACHE_EXPIRATION = 30;@Autowiredprivate WriteBehindCacheManager<Long, User> cacheManager;@Autowiredprivate UserRepository userRepository;@PostConstructpublic void init() {// 注冊用戶數據寫入器cacheManager.registerWriter(CACHE_PREFIX, this::saveUserToDb);}private void saveUserToDb(Long userId, User user) {userRepository.save(user);}public void updateUser(User user) {// 更新僅寫入緩存,異步寫入數據庫cacheManager.put(CACHE_PREFIX, user.getId(), user, CACHE_EXPIRATION, TimeUnit.MINUTES);}
}

優缺點分析

優點

  • 顯著提高寫操作性能,減少響應延遲
  • 通過批量操作減輕數據庫壓力
  • 平滑處理寫入峰值,提高系統吞吐量

缺點

  • 存在數據一致性窗口期,不適合強一致性要求的場景
  • 系統崩潰可能導致未寫入的數據丟失
  • 實現復雜,需要處理失敗重試和沖突解決

適用場景

  • 高并發寫入場景,如日志記錄、統計數據
  • 對寫操作延遲敏感但對一致性要求不高的應用
  • 數據庫寫入是系統瓶頸的場景

策略五:刷新過期(Refresh-Ahead)策略

工作原理

Refresh-Ahead策略預測性地在緩存過期前進行更新:

  1. 緩存設置正常的過期時間
  2. 當訪問接近過期的緩存項時,觸發異步刷新
  3. 用戶始終訪問的是已緩存的數據,避免直接查詢數據庫的延遲

代碼示例

@Component
public class RefreshAheadCacheManager<K, V> {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Autowiredprivate ThreadPoolTaskExecutor refreshExecutor;private final ConcurrentHashMap<String, CacheLoader<K, V>> loaders = new ConcurrentHashMap<>();// 刷新閾值,當過期時間剩余不足閾值比例時觸發刷新private final double refreshThreshold = 0.75; // 75%public void registerLoader(String cachePrefix, CacheLoader<K, V> loader) {loaders.put(cachePrefix, loader);}@SuppressWarnings("unchecked")public V get(String cachePrefix, K key, long expiration, TimeUnit timeUnit) {String cacheKey = cachePrefix + key;// 1. 獲取緩存項和其TTLV value = (V) redisTemplate.opsForValue().get(cacheKey);Long ttl = redisTemplate.getExpire(cacheKey, TimeUnit.MILLISECONDS);if (value != null) {// 2. 如果緩存存在但接近過期,觸發異步刷新if (ttl != null && ttl > 0) {long expirationMs = timeUnit.toMillis(expiration);if (ttl < expirationMs * (1 - refreshThreshold)) {refreshAsync(cachePrefix, key, cacheKey, expiration, timeUnit);}}return value;}// 3. 緩存不存在,同步加載return loadAndCache(cachePrefix, key, cacheKey, expiration, timeUnit);}private void refreshAsync(String cachePrefix, K key, String cacheKey, long expiration, TimeUnit timeUnit) {refreshExecutor.execute(() -> {try {loadAndCache(cachePrefix, key, cacheKey, expiration, timeUnit);} catch (Exception e) {// 異步刷新失敗,記錄日志但不影響當前請求log.error("Failed to refresh cache for key {}: {}", cacheKey, e.getMessage());}});}private V loadAndCache(String cachePrefix, K key, String cacheKey, long expiration, TimeUnit timeUnit) {CacheLoader<K, V> loader = loaders.get(cachePrefix);if (loader == null) {throw new IllegalStateException("No cache loader registered for prefix: " + cachePrefix);}// 從數據源加載V value = loader.load(key);// 更新緩存if (value != null) {redisTemplate.opsForValue().set(cacheKey, value, expiration, timeUnit);}return value;}
}

使用示例:

@Service
public class ProductServiceRefreshAhead {private static final String CACHE_PREFIX = "product:";private static final long CACHE_EXPIRATION = 60; // 1小時@Autowiredprivate RefreshAheadCacheManager<String, Product> cacheManager;@Autowiredprivate ProductRepository productRepository;@PostConstructpublic void init() {// 注冊產品數據加載器cacheManager.registerLoader(CACHE_PREFIX, this::loadProductFromDb);}private Product loadProductFromDb(String productId) {return productRepository.findById(productId).orElse(null);}public Product getProduct(String productId) {return cacheManager.get(CACHE_PREFIX, productId, CACHE_EXPIRATION, TimeUnit.MINUTES);}
}

線程池配置

@Configuration
public class ThreadPoolConfig {@Beanpublic ThreadPoolTaskExecutor refreshExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(20);executor.setQueueCapacity(100);executor.setThreadNamePrefix("cache-refresh-");executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());executor.initialize();return executor;}
}

優缺點分析

優點

  • 用戶始終訪問緩存數據,避免因緩存過期導致的延遲
  • 異步刷新減輕了數據庫負載峰值
  • 緩存命中率高,用戶體驗更好

缺點

  • 實現復雜度高,需要額外的線程池管理
  • 預測算法可能不準確,導致不必要的刷新
  • 對于很少訪問的數據,刷新可能是浪費

適用場景

  • 對響應時間要求苛刻的高流量系統
  • 數據更新頻率可預測的場景
  • 數據庫資源有限但緩存容量充足的系統

策略六:最終一致性(Eventual Consistency)策略

工作原理

最終一致性策略基于分布式事件系統實現數據同步:

  1. 數據變更時發布事件到消息隊列
  2. 緩存服務訂閱相關事件并更新緩存
  3. 即使某些操作暫時失敗,最終系統也會達到一致狀態

代碼示例

首先定義數據變更事件:

@Data
@AllArgsConstructor
public class DataChangeEvent {private String entityType;private String entityId;private String operation; // CREATE, UPDATE, DELETEprivate String payload;   // JSON格式的實體數據
}

實現事件發布者:

@Component
public class DataChangePublisher {@Autowiredprivate KafkaTemplate<String, DataChangeEvent> kafkaTemplate;private static final String TOPIC = "data-changes";public void publishChange(String entityType, String entityId, String operation, Object entity) {try {// 將實體序列化為JSONString payload = new ObjectMapper().writeValueAsString(entity);// 創建事件DataChangeEvent event = new DataChangeEvent(entityType, entityId, operation, payload);// 發布到KafkakafkaTemplate.send(TOPIC, entityId, event);} catch (Exception e) {log.error("Failed to publish data change event", e);throw new RuntimeException("Failed to publish event", e);}}
}

實現事件消費者更新緩存:

@Component
@Slf4j
public class CacheUpdateConsumer {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;private static final long CACHE_EXPIRATION = 30;@KafkaListener(topics = "data-changes")public void handleDataChangeEvent(DataChangeEvent event) {try {String cacheKey = buildCacheKey(event.getEntityType(), event.getEntityId());switch (event.getOperation()) {case "CREATE":case "UPDATE":// 解析JSON數據Object entity = parseEntity(event.getPayload(), event.getEntityType());// 更新緩存redisTemplate.opsForValue().set(cacheKey, entity, CACHE_EXPIRATION, TimeUnit.MINUTES);log.info("Updated cache for {}: {}", cacheKey, event.getOperation());break;case "DELETE":// 刪除緩存redisTemplate.delete(cacheKey);log.info("Deleted cache for {}", cacheKey);break;default:log.warn("Unknown operation: {}", event.getOperation());}} catch (Exception e) {log.error("Error handling data change event: {}", e.getMessage(), e);// 失敗處理:可以將失敗事件放入死信隊列等}}private String buildCacheKey(String entityType, String entityId) {return entityType.toLowerCase() + ":" + entityId;}private Object parseEntity(String payload, String entityType) throws JsonProcessingException {// 根據實體類型選擇反序列化目標類Class<?> targetClass = getClassForEntityType(entityType);return new ObjectMapper().readValue(payload, targetClass);}private Class<?> getClassForEntityType(String entityType) {switch (entityType) {case "User": return User.class;case "Product": return Product.class;// 其他實體類型default: throw new IllegalArgumentException("Unknown entity type: " + entityType);}}
}

使用示例:

@Service
@Transactional
public class UserServiceEventDriven {@Autowiredprivate UserRepository userRepository;@Autowiredprivate DataChangePublisher publisher;public User createUser(User user) {// 1. 保存用戶到數據庫User savedUser = userRepository.save(user);// 2. 發布創建事件publisher.publishChange("User", savedUser.getId().toString(), "CREATE", savedUser);return savedUser;}public User updateUser(User user) {// 1. 更新用戶到數據庫User updatedUser = userRepository.save(user);// 2. 發布更新事件publisher.publishChange("User", updatedUser.getId().toString(), "UPDATE", updatedUser);return updatedUser;}public void deleteUser(Long userId) {// 1. 從數據庫刪除用戶userRepository.deleteById(userId);// 2. 發布刪除事件publisher.publishChange("User", userId.toString(), "DELETE", null);}
}

優缺點分析

優點

  • 支持分布式系統中的數據一致性
  • 削峰填谷,減輕系統負載峰值
  • 服務解耦,提高系統彈性和可擴展性

缺點

  • 一致性延遲,只能保證最終一致性
  • 實現和維護更復雜,需要消息隊列基礎設施
  • 可能需要處理消息重復和亂序問題

適用場景

  • 大型分布式系統
  • 可以接受短暫不一致的業務場景
  • 需要解耦數據源和緩存更新邏輯的系統

緩存更新策略選擇指南

選擇合適的緩存更新策略需要考慮以下因素:

1. 業務特性考量

業務特征推薦策略
讀多寫少Cache-Aside 或 Read-Through
寫密集型Write-Behind
高一致性需求Write-Through
響應時間敏感Refresh-Ahead
分布式系統最終一致性

2. 資源限制考量

資源約束推薦策略
內存限制Cache-Aside(按需緩存)
數據庫負載高Write-Behind(減輕寫壓力)
網絡帶寬受限Write-Behind 或 Refresh-Ahead

3. 開發復雜度考量

復雜度要求推薦策略
簡單實現Cache-Aside
中等復雜度Read-Through 或 Write-Through
高復雜度但高性能Write-Behind 或 最終一致性

結論

緩存更新是Redis應用設計中的核心挑戰,沒有萬能的策略適用于所有場景。根據業務需求、數據特性和系統資源,選擇合適的緩存更新策略或組合多種策略才是最佳實踐。

在實際應用中,可以根據不同數據的特性選擇不同的緩存策略,甚至在同一個系統中組合多種策略,以達到性能和一致性的最佳平衡。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/904532.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/904532.shtml
英文地址,請注明出處:http://en.pswp.cn/news/904532.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

項目優先級頻繁變動,如何應對?

項目優先級頻繁變動是許多公司和團隊在工作中常遇到的挑戰。 這種情況通常由業務需求變化、市場壓力或高層決策調整等因素引起&#xff0c;常常讓團隊成員感到困惑和不安。首先&#xff0c;制定明確的優先級管理框架是應對項目優先級變動的基礎&#xff0c; 通過清晰的優先級排…

屏蔽力 | 在復雜世界中從內耗到成長的轉變之道

注&#xff1a;本文為“屏蔽力”相關文章合輯。 略作重排&#xff0c;未全整理。 世上的事再復雜&#xff0c;不外乎這三種 原創 小鹿 讀者 2022 年 12 月 02 日 18 : 27 甘肅 文 / 小鹿 在這世上&#xff0c;每天都有大事小事、瑣事煩事。我們總為世事奔波忙碌&#xff0c;…

[數據處理] 3. 數據集讀取

&#x1f44b; 你好&#xff01;這里有實用干貨與深度分享?? 若有幫助&#xff0c;歡迎&#xff1a;? &#x1f44d; 點贊 | ? 收藏 | &#x1f4ac; 評論 | ? 關注 &#xff0c;解鎖更多精彩&#xff01;? &#x1f4c1; 收藏專欄即可第一時間獲取最新推送&#x1f514;…

IIS配置SSL

打開iis 如果搜不到iis&#xff0c;要先開 再搜就打得開了 cmd中找到本機ip 用http訪問本機ip 把原本的http綁定刪了 再用http訪問本機ip就不行了 只能用https訪問了

RabbitMQ的交換機

一、三種交換機模式 核心區別對比?? ??特性????廣播模式&#xff08;Fanout&#xff09;????路由模式&#xff08;Direct&#xff09;????主題模式&#xff08;Topic&#xff09;????路由規則??無條件復制到所有綁定隊列精確匹配 Routing Key通配符匹配…

(2025,AR,NAR,GAN,Diffusion,模型對比,數據集,評估指標,性能對比)文本到圖像的生成和編輯:綜述

【本文為我在去年完成的綜述&#xff0c;因某些原因未能及時投稿&#xff0c;但本文仍能為想要全面了解文本到圖像的生成和編輯的學習者提供可靠的參考。目前本文已投稿 ACM Computing Surveys。 完整內容可在如下鏈接獲取&#xff0c;或在 Q 群群文件獲取。 中文版為論文初稿&…

MCU怎么運行深度學習模型

Gitee倉庫 git clone https://gitee.com/banana-peel-x/freedom-learn.git項目場景&#xff1a; 解決面試時遺留的問題&#xff0c;面試官提了兩個問題&#xff1a;1.單片機能跑深度學習的模型嗎&#xff1f; 2.為什么FreeRTOS要采用SVC去觸發第一個任務&#xff0c;只用Pend…

多模態學習(一)——從 Image-Text Pair 到 Instruction-Following 格式

前言 在多模態任務中&#xff08;例如圖像問答、圖像描述等&#xff09;&#xff0c;為了使用指令微調&#xff08;Instruction Tuning&#xff09;提升多模態大模型的能力&#xff0c;我們需要構建成千上萬條**指令跟隨&#xff08;instruction-following&#xff09;**格式的…

MySQL基礎關鍵_011_視圖

目 錄 一、說明 二、操作 1.創建視圖 2.創建可替換視圖 3.修改視圖 4.刪除視圖 5.對視圖內容的增、刪、改 &#xff08;1&#xff09;增 &#xff08;2&#xff09;改 &#xff08;3&#xff09;刪 一、說明 只能將 DQL 語句創建為視圖&#xff1b;作用&#xff1a; …

『深夜_MySQL』數據庫操作 字符集與檢驗規則

2.庫的操作 2.1 創建數據庫 語法&#xff1a; CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [,create_specification]….]create_spcification:[DEFAULT] CHARACTER SET charset_nam[DEFAULT] COLLATE collation_name說明&#xff1a; 大寫的表示關鍵字 …

Spark jdbc寫入崖山等國產數據庫失敗問題

隨著互聯網、信息產業的大發展、以及地緣政治的變化,網絡安全風險日益增長,網絡安全關乎國家安全。因此很多的企業,開始了國產替代的腳步,從服務器芯片,操作系統,到數據庫,中間件,逐步實現信息技術自主可控,規避外部技術制裁和風險。 就數據庫而言,目前很多的國產數據…

數字化轉型-4A架構之應用架構

系列文章 數字化轉型-4A架構&#xff08;業務架構、應用架構、數據架構、技術架構&#xff09;數字化轉型-4A架構之業務架構 前言 應用架構AA&#xff08;Application Architecture&#xff09;是規劃支撐業務的核心系統與功能模塊&#xff0c;實現端到端協同。 一、什么是應…

格雷狼優化算法`GWO 通過模擬和優化一個信號處理問題來最大化特定頻率下的功率

這段代碼是一個Python程序,它使用了多個科學計算庫,包括`random`、`numpy`、`matplotlib.pyplot`、`scipy.signal`和`scipy.signal.windows`。程序的主要目的是通過模擬和優化一個信號處理問題來最大化特定頻率下的功率。 4. **定義類`class_model`**: - 這個類包含了信號…

中級網絡工程師知識點1

1.1000BASE-CX:銅纜,最大傳輸距離為25米 1000BASE-LX:傳輸距離可達3000米 1000BASE-ZX:超過10km 2.RSA加密算法的安全性依賴于大整數分解問題的困難性 3.網絡信息系統的可靠性測度包括有效性,康毀性,生存性 4.VLAN技術所依據的協議是IEEE802.1q IEEE802.15標準是針…

2025年五一數學建模A題【支路車流量推測】原創論文講解

大家好呀&#xff0c;從發布賽題一直到現在&#xff0c;總算完成了2025年五一數學建模A題【支路車流量推測】完整的成品論文。 給大家看一下目錄吧&#xff1a; 摘 要&#xff1a; 一、問題重述 二&#xff0e;問題分析 2.1問題一 2.2問題二 2.3問題三 2.4問題四 2.5 …

性能優化實踐:渲染性能優化

性能優化實踐&#xff1a;渲染性能優化 在Flutter應用開發中&#xff0c;渲染性能直接影響用戶體驗。本文將從渲染流程分析入手&#xff0c;深入探討Flutter渲染性能優化的關鍵技術和最佳實踐。 一、Flutter渲染流程解析 1.1 渲染流水線 Flutter的渲染流水線主要包含以下幾…

linux基礎學習--linux磁盤與文件管理系統

linux磁盤與文件管理系統 1.認識linux系統 1.1 磁盤組成與分區的復習 首先了解磁盤的物理組成,主要有: 圓形的碟片(主要記錄數據的部分)。機械手臂,與在機械手臂上的磁頭(可擦寫碟片上的內容)。主軸馬達,可以轉動碟片,讓機械手臂的磁頭在碟片上讀寫數據。 數據存儲…

DIFY教程第五彈:科研論文翻譯與SEO翻譯應用

科研論文翻譯 我可以在工作流案例中結合聊天大模型來實現翻譯工具的功能&#xff0c;具體的設計如下 在開始節點中接收一個輸入信息 content 然后在 LLM 模型中我們需要配置一個 CHAT 模型&#xff0c;這里選擇了 DeepSeek-R1 64K 的聊天模型&#xff0c;注意需要在這里設置下…

【Redis】哨兵機制和集群

&#x1f525;個人主頁&#xff1a; 中草藥 &#x1f525;專欄&#xff1a;【中間件】企業級中間件剖析 一、哨兵機制 Redis的主從復制模式下&#xff0c;一旦主節點由于故障不能提供服務&#xff0c;需要人工的進行主從切換&#xff0c;同時需要大量的客戶端需要被通知切換到…

注意力機制(Attention)

1. 注意力認知和應用 AM&#xff1a; Attention Mechanism&#xff0c;注意力機制。 根據眼球注視的方向&#xff0c;采集顯著特征部位數據&#xff1a; 注意力示意圖&#xff1a; 注意力機制是一種讓模型根據任務需求動態地關注輸入數據中重要部分的機制。通過注意力機制&…