【SSDB】【python】刪除千萬級zset大key

背景

最近接到需求,要刪除ssdb中一個8000+w個member的zset。
該SSDB架構爲雙主模式+Keepalived構建的高可用。
處理時長要求在一天內完成。

相關SSDB-API

  • zrange:zrange name offset limit,根據下標索引區間 [offset, offset + limit) 獲取 key-score 對, 下標從 0 開始. zrrange 是反向順序獲取.(注意! 本方法在 offset 越來越大時, 會越慢!)

  • zkeys:zkeys name key_start score_start score_end limit,列出 zset 中的 key 列表

  • zscan:zscan name key_start score_start score_end limit,列出 zset 中處於區間 (key_start+score_start, score_end] 的 key-score 列表. 如果 key_start 爲空, 那麼對應權重值大於或者等於 score_start 的 key 將被返回. 如果 key_start 不爲空, 那麼對應權重值大於 score_start 的 key, 或者大於 key_start 且對應權重值等於 score_start 的 key 將被返回.也就是說, 返回的 key 在 (key.score == score_start && key > key_start || key.score > score_start), 並且key.score <= score_end 區間. 先判斷 score_start, score_end, 然後判斷 key_start._,("", “”] 表示整個區間.

  • zclear:zclear name,刪除 zset 中的所有 key.

  • zremrangebyscore:zremrangebyscore name start end,刪除權重處於區間 [start,end] 的元素.

  • zremrangebyrank:zremrangebyrank name start end,刪除位置處於區間 [start,end] 的元素.

  • zdel:zdel name key,獲取 zset 中的指定 key.

  • multi_zdel :multi_zdel name key1 key2 …,批量刪除 zset 中的 key.

Redis與SSDB命令映射表

在這裏插入圖片描述

解決思路

  • 思路1:通過zclear直接刪key

  • 思路2:遍歷zset的member(zkeys、zrange、zscan),然後刪除member(zdel)

  • 思路3:通過刪除排名的方式進行刪除(zremrangebyrank)

最終方案

使用思路3,但是爲了記錄刪除數據,使用了zrange+zdel+pipeline的方法,具體實現如下。
在從庫中進行操作。

demo

#encoding: utf-8
import redis

def del_big_zset(rip, rport, passwd, key)
	rpool = redis.ConnectionPool(host = rip, port = rport, db = 0, password = passwd)
	r = redis.Redis(connection_pool=rpool)
	pipeline = r.pipeline(transaction=False)
	count  = 0
	key_size = r.zcard(key)
	start = 0
	end = 1000
	while(key_size > 1):
		member_list = r.zrange(name=key,start=start,end=end)
		for member in member_list:
			print "%s" % (member)
			pipeline.zrem(key, member)
		result = pipeline.execute()
		key_size = r.zcard(key)

效果

每秒清除速度是5k左右,最終預計5小時內完成清理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章