亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么把Reids的7千萬個Key刪完

發布時間:2021-10-28 17:41:08 來源:億速云 閱讀:108 作者:iii 欄目:web開發

本篇內容主要講解“怎么把Reids的7千萬個Key刪完”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么把Reids的7千萬個Key刪完”吧!

難點分析

共用Redis服務集群

由于這條業務線的數據在Redis大概在3G左右,完全沒必要單獨建一個Redis服務集群,本著能節約就節約的態度,當初就決定和其他項目共享一個集群(這個集群配置:16個節點,128G內存,還算豪華吧~)集群配置如下:

怎么把Reids的7千萬個Key刪完

在這種共用集群的情況下,導致無法簡單粗暴的釋放。因此只能選擇刪除Key的方式。

Key命名不規范

要刪除Key,首先就要精準的定位出哪些Key需要刪除,如果勿刪Key,會影響到其他服務正常運轉!如果Key本身設置了過期時間,但有些數據需是持久化的。然而那該死的項目經理一直催項目進度,導致開發人員在開發過程中很多地方都沒有設計到位,比如Redis Key散落在項目代碼的每個角落;比如命名不是很規范。真不知道是怎么review代碼!哦,想必是沒有時間review,那該死的項目經理……

我隨便截個支付服務中的Key命名:

怎么把Reids的7千萬個Key刪完

怎么樣?是不是覺得我們開發人員寫的代碼很low~別笑,在實際工作中,還有比這更low的!希望你別遇到,不然真的很痛苦~

解決思路

經過以上的分析,我們簡單歸納如下:

  •  我們真正關心的是那些未設置過期時間的Key

  •  不能誤刪除Key,否則下個月績效也沒了

  •  由于Key的命名及使用及其不規范,導致Key的定位難度很大

看來,通過scan命令掃描匹配Key的方式行不通了。只能通過人肉搜索了~

幸而Idea的搜索大法好,這個項目中使用的是spring-boot-starter-data-redis.因此我通過搜索RedisTemplate和StringRedisTemplate定位所有操作redis的代碼,具體步驟如下:

1、通過這些代碼統計出Key的前綴并錄入到文本中;

2、通過python腳本把載入文中中的的Key并在后面加上“*”通配符;

3、通過python腳本通過scan命令掃描出這些key;

4、為了便于檢查,我們并沒有直接使用del命令刪除key,在刪除key之前,先通過debug object key的方式得到其序列化的長度,再執行刪除并返回序列化長度。這樣,我們就可以統計出所有key的序列化長度來得到我們釋放的空間大小。關鍵代碼如下: 

def get_key(rdbConn,start):         try:         keys_list = rdbConn.scan(start,count=2000)         return keys_list         exceptException,e:         print e     ''' Redis DEBUG OBJECT command got key info '''     def get_key_info(rdbConn,keyName):         try:         rpiple = rdbConn.pipeline()         rpiple.type(keyName)         rpiple.debug_object(keyName)         rpiple.ttl(keyName)         key_info_list = rpiple.execute()         return key_info_list         exceptException,e:         print"INFO : ",e     def redis_key_static(key_info_list):         keyType = key_info_list[0]         keySize = key_info_list[1]['serializedlength']         keyTtl = key_info_list[2]         key_size_static(keyType,keySize,keyTtl)

通過以上方式,能夠統計出究竟釋放了多少內存了。

由于這個集群是有這么接近7千萬個key:

怎么把Reids的7千萬個Key刪完

因此,等到了第二天天亮,我睡眼朦朧的看了一下,終于刪除完畢了,時間07:13...早高峰即將來臨……

知恥而后勇

從來沒有經歷過因業務下線而清除資源的經驗。這次事情真心讓我覺得細微之處見真功夫的道理。如果一開始我們就能夠遵循開發規范來使用和設計redis key,也不至于浪費這么多時間。為了讓key的命名和使用更加規范,以及今后避免再次遇到這種情況,下午睡醒之后,我就在redis公共組件庫里面添加了一個配置和自定義了key序列化,代碼如下:

@ConfigurationProperties(prefix = "spring.redis.prefix")  publicclassRedisKeyPrefixProperties{      privateBoolean enable = Boolean.TRUE;      privateString key;      publicBoolean getEnable() {          return enable;      }      publicvoid setEnable(Boolean enable) {          this.enable = enable;      }      publicString getKey() {          return key;      }      publicvoid setKey(String key) {          this.key = key;      }  }
/**   * @desc 對字符串序列化新增前綴   * @author create by liming sun on 2020-07-21 14:09:51   */  publicclassPrefixStringKeySerializerextendsStringRedisSerializer{      privateCharset charset = StandardCharsets.UTF_8;      privateRedisKeyPrefixProperties prefix;      publicPrefixStringKeySerializer(RedisKeyPrefixProperties prefix) {          super();          this.prefix = prefix;      }      @Override      publicString deserialize(@Nullablebyte[] bytes) {          String saveKey = newString(bytes, charset);          if(prefix.getEnable() != null&& prefix.getEnable()) {              String prefixKey = spliceKey(prefix.getKey());              int indexOf = saveKey.indexOf(prefixKey);              if(indexOf > 0) {                  saveKeysaveKey = saveKey.substring(indexOf);              }          }          return(saveKey.getBytes() == null? null: saveKey);      }      @Override      publicbyte[] serialize(@NullableString key) {          if(prefix.getEnable() != null&& prefix.getEnable()) {              key = spliceKey(prefix.getKey()) + key;          }          return(key == null? null: key.getBytes(charset));      }      privateString spliceKey(String prefixKey) {          if(StringUtils.isNotBlank(prefixKey) && !prefixKey.endsWith(":")) {              prefixKeyprefixKey = prefixKey + "::";          }          return prefixKey;      }  }

使用效果

為了避免再次發生這種工作低效而又不得不做的事情,我們在開發規范中規定,新項目中redis的使用必須設置此配置,前綴就設置為:項目編號。另外,一個模塊中的key必須統一定義在二方庫的RedisKeyConstant類中。配置如下:

spring:      redis:          prefix:              enable: true              key: E00P01
@Bean     publicRedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {         RedisTemplate<String, Object> redisTemplate = newRedisTemplate<>();         redisTemplate.setConnectionFactory(redisConnectionFactory);         // 支持key前綴設置的key Serializer         redisTemplate.setKeySerializer(newPrefixStringKeySerializer());         redisTemplate.setValueSerializer(newGenericJackson2JsonRedisSerializer());         return redisTemplate;     }

通過以上方式,我們至少可以從項目維度來區分出key,避免了多個項目之間共用同一個集群時而導致重復key的問題。從項目維度對key進行了劃分。更方便管理和運維。如果對于key的管理粒度要求更細,我們甚至可以細化到具體業務維度。我們在測試環境進行了壓測,增加key前綴對redis性能幾乎沒有影響。性能方面能接受。

到此,相信大家對“怎么把Reids的7千萬個Key刪完”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

刚察县| 莱西市| 乌拉特后旗| 沙河市| 乐安县| 苍南县| 乌海市| 仪陇县| 旌德县| 昆明市| 德惠市| 邵阳市| 和政县| 五河县| 安岳县| 北票市| 林州市| 天全县| 若尔盖县| 成安县| 大庆市| 那坡县| 三穗县| 乌拉特中旗| 石门县| 安溪县| 延吉市| 获嘉县| 闵行区| 教育| 玛曲县| 广汉市| 津市市| 逊克县| 内丘县| 扎囊县| 唐河县| 叶城县| 池州市| 大名县| 木兰县|