Java操作redis設定第二天凌晨過期的解決方案是什麼
Java操作redis設定第二天凌晨過期
場景
在做查詢資料的時候,遇到了需要設定資料在redis中第二天過期的問題,但是redis又沒有對應的API,就只好自己來解決了
思路
計算出第二天凌晨與當前時間的時間差,將該時間差設定為redis的過期時間,就可以達到我們想要的效果
程式碼
/** * 计算第二天凌晨与当前时间的时间差秒数 * @param * @return java.lang.Long * @author shy * @date 2021/3/12 18:10 */ public static Long getNowToNextDaySeconds() { Calendar cal = Calendar.getInstance(); cal.add(Calendar.DAY_OF_YEAR, 1); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.MILLISECOND, 0); return (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000; }
拿到了時間差,剩下的基本上就沒什麼問題了。
附上Redis工具類別:
/** * 操作redis * @author shy * @date 2020/12/10 10:01 */ @Service public class RedisService { @Autowired private StringRedisTemplate stringRedisTemplate; @Autowired private RedisTemplate<String, Object> redisTemplate; /** * 判断String类型key是否存在 * * @param key * @return * @author shy * @date 2018年11月13日 下午1:40:37 */ public boolean hasStringKey(String key) { if (StringUtils.isBlank(key)) { throw new EmptyParameterException(); } return stringRedisTemplate.opsForValue().getOperations().hasKey(key); } /** * 判断String类型key是否存在 * * @param key * @return * @author shy * @date 2018年11月13日 下午1:43:51 */ public boolean nonStringKey(String key) { return !hasStringKey(key); } /** * 设置String类型key,String类型value,过期时间timeout,TimeUnit * * @param key * @param value * @param timeout * @param timeUnit * @author shy * @date 2018年12月10日13:53:38 */ public void setStringKey(String key, String value, Long timeout, TimeUnit timeUnit) { if (StringUtils.isBlank(key) || Objects.isNull(timeout)) { throw new EmptyParameterException(); } stringRedisTemplate.opsForValue().set(key, value, timeout, timeUnit); } public void setStringKey(String key, String value) { if (StringUtils.isBlank(key)) { throw new EmptyParameterException(); } stringRedisTemplate.opsForValue().set(key, value); } /** * 获取String类型value * * @param key * @return * @author shy * @date 2018年11月12日 下午7:09:31 */ public String getStringValue(String key) { if (StringUtils.isBlank(key)) { throw new EmptyParameterException(); } return stringRedisTemplate.opsForValue().get(key); } /** * 获取Key的过期时间 * * @param key * @return * @author shy * @date 2019年4月25日17:28:36 */ public Long getExpire(String key) { if (StringUtils.isBlank(key)) { throw new EmptyParameterException(); } return stringRedisTemplate.getExpire(key); } /** * 设置Key的过期时间 * * @param key * @return * @author shy * @date 2019年4月25日17:28:36 */ public Boolean setExpire(String key,Long timeout, TimeUnit timeUnit) { if (StringUtils.isBlank(key)) { throw new EmptyParameterException(); } return stringRedisTemplate.expire(key, timeout, timeUnit); } /** * value自增+n * @param key * @return * @author shy * @date 2019年4月8日15:54:30 */ public Long setIncrementValue(String key) { if (StringUtils.isBlank(key)) { throw new EmptyParameterException(); } return stringRedisTemplate.opsForValue().increment(key, 1L); } /** * 设置String类型key,Object类型value,过期时间timeout * * @param key * @param value * @param timeout * @author shy * @date 2018年12月10日13:54:07 */ public void setObjectKey(String key, Object value, Long timeout,TimeUnit time) { if (StringUtils.isBlank(key) || Objects.isNull(timeout)) { throw new EmptyParameterException(); } redisTemplate.opsForValue().set(key, value, timeout, time); } public void setObjectKey(String key, Object value) { if (StringUtils.isBlank(key)) { throw new EmptyParameterException(); } redisTemplate.opsForValue().set(key, value); } /** * 获取Object类型value * * @param key * @param clazz * @return * @author shy * @date 2019年11月6日10:01:30 */ @SuppressWarnings("unchecked") public <T> T getObjectValue(String key, Class<T> clazz) { if (StringUtils.isBlank(key)) { return null; } return (T) redisTemplate.opsForValue().get(key); } /** * 移除单个String类型key * * @param key * @author shy * @date 2018年11月13日 上午10:42:01 */ public void removeSingleStringKey(String key) { if (StringUtils.isBlank(key)) { throw new EmptyParameterException(); } stringRedisTemplate.opsForValue().getOperations().delete(key); } /** * 移除Collection<String>类型keys * * @param keys * @author shy * @date 2018年11月13日 下午3:15:16 */ public void removeMultiStringKey(Collection<String> keys) { if (CollectionUtils.isNotEmpty(keys)) { stringRedisTemplate.opsForValue().getOperations().delete(keys); } } /** * redis key 模糊查询 * @author shy * @date 2021年1月4日 上午11:21:45 * @param key * @return */ public Set<String> queryStringKeys(String key) { return redisTemplate.keys(key + "*"); } }
redis過期策略功能介紹
我們在使用redis時,一般會設定一個過期時間,當然也有不設定過期時間的,也就是永久不過期。
當我們設定了過期時間,redis是如何判斷是否過期,以及根據什麼策略來進行刪除的。
設定過期時間
我們set key的時候,可以給一個expire time,就是過期時間,指定這個key比如說只能存活一個小時,假設你設定一批key存活一小時,那麼接下來一小時後,redis是如何對這批key進行刪除的?
答案是:定期刪除 惰性刪除。
所謂定期刪除是指redis預設每隔100ms就隨機抽取一些設定了過期時間的key,檢查其是否過期,如果過期就刪除。每隔100ms遍歷所有設定過期時間的key會導致效能大幅下降,請注意。 Redis實際上會在每100毫秒內隨機選擇一些key進行檢查和刪除。
但是問題是定期刪除可能會導致很多過期key到了時間並沒有被刪除,所以要惰性刪除,就是說在你獲取某個key的時候,redis會檢查一下,這個key如果設定了過期時間那麼是否過期了?如果過期了就會刪除。
透過上述兩種手段結合起來,保證過期的key一定會被幹掉。到了過期時間並不會自動刪除所有過期的key,因此過期後記憶體佔用並不會降低。
但其實這還是有問題的,如果定期刪除漏掉了很多過期key,然後沒有及時去查也就沒走惰性刪除,就會導致大量過期key堆積在內存裡耗費redis內存,這種情況如何處理?
答案是:走記憶體淘汰機制。
記憶體淘汰
如果redis的記憶體佔用過多的時候,此時會進行一些淘汰,有以下一些策略:
#noeviction
:當記憶體不足以容納新寫入資料時,新寫入資料會報錯,這個實際場景一般不會使用。allkeys-lru
:當記憶體不足以容納新寫入資料時,在鍵空間中,移除最少使用的key(這個是最常用的)allkeys-random
:當記憶體不足以容納新寫入資料時,在鍵空間中,隨機移除某個key,這個一般用的比較少。volatile-lru
:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,移除最近最少使用的key 。volatile-random
:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,隨機移除某個key。volatile-ttl
:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,有更早過期時間的key優先移除。
記憶體淘汰會觸發淘汰條件刪除某些key,這也是造成key沒有設定過期時間而遺失的原因。
以上是Java操作redis設定第二天凌晨過期的解決方案是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

Redis集群模式通過分片將Redis實例部署到多個服務器,提高可擴展性和可用性。搭建步驟如下:創建奇數個Redis實例,端口不同;創建3個sentinel實例,監控Redis實例並進行故障轉移;配置sentinel配置文件,添加監控Redis實例信息和故障轉移設置;配置Redis實例配置文件,啟用集群模式並指定集群信息文件路徑;創建nodes.conf文件,包含各Redis實例的信息;啟動集群,執行create命令創建集群並指定副本數量;登錄集群執行CLUSTER INFO命令驗證集群狀態;使

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP和Python各有優勢,適合不同場景。 1.PHP適用於web開發,提供內置web服務器和豐富函數庫。 2.Python適合數據科學和機器學習,語法簡潔且有強大標準庫。選擇時應根據項目需求決定。

要從 Redis 讀取隊列,需要獲取隊列名稱、使用 LPOP 命令讀取元素,並處理空隊列。具體步驟如下:獲取隊列名稱:以 "queue:" 前綴命名,如 "queue:my-queue"。使用 LPOP 命令:從隊列頭部彈出元素並返回其值,如 LPOP queue:my-queue。處理空隊列:如果隊列為空,LPOP 返回 nil,可先檢查隊列是否存在再讀取元素。

在CentOS系統上,您可以通過修改Redis配置文件或使用Redis命令來限制Lua腳本的執行時間,從而防止惡意腳本佔用過多資源。方法一:修改Redis配置文件定位Redis配置文件:Redis配置文件通常位於/etc/redis/redis.conf。編輯配置文件:使用文本編輯器(例如vi或nano)打開配置文件:sudovi/etc/redis/redis.conf設置Lua腳本執行時間限制:在配置文件中添加或修改以下行,設置Lua腳本的最大執行時間(單位:毫秒)

PHP成為許多網站首選技術棧的原因包括其易用性、強大社區支持和廣泛應用。 1)易於學習和使用,適合初學者。 2)擁有龐大的開發者社區,資源豐富。 3)廣泛應用於WordPress、Drupal等平台。 4)與Web服務器緊密集成,簡化開發部署。
