RedisObject.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. import redis
  2. from Ansjer.config import SERVER_HOST
  3. # 本地调试把注释打开
  4. # SERVER_HOST = '127.0.0.1'
  5. class RedisObject:
  6. def __init__(self, db=0, host=SERVER_HOST):
  7. self.POOL = redis.ConnectionPool(host=host, port=6379, db=db)
  8. self.CONN = redis.Redis(connection_pool=self.POOL)
  9. def set_data(self, key, val, expire=0):
  10. try:
  11. self.CONN.set(key, val)
  12. if expire > 0:
  13. self.CONN.expire(key, expire)
  14. except Exception as e:
  15. return False
  16. else:
  17. return True
  18. def set_expire(self, key, ttl):
  19. self.CONN.expire(key, ttl)
  20. def get_data(self, key):
  21. try:
  22. val = self.CONN.get(key)
  23. except Exception as e:
  24. print(repr(e))
  25. return False
  26. else:
  27. if val:
  28. return val.decode('utf-8')
  29. else:
  30. return False
  31. def del_data(self, key):
  32. try:
  33. val = self.CONN.delete(key)
  34. except Exception as e:
  35. print(repr(e))
  36. return False
  37. else:
  38. return True
  39. def get_size(self):
  40. return self.CONN.dbsize()
  41. # 向列表插入数据
  42. def rpush(self, name, val):
  43. self.CONN.rpush(name, val)
  44. # 向列表插入列表数据
  45. def rpush_list(self, name, list_val):
  46. self.CONN.rpush(name, *list_val)
  47. def lpop(self, name):
  48. val = self.CONN.lpop(name)
  49. if val:
  50. return val.decode('utf-8')
  51. else:
  52. return False
  53. # 获取列表长度
  54. def llen(self, name):
  55. return self.CONN.llen(name=name)
  56. # 获取列表所有数据
  57. def lrange(self, name, start, end):
  58. return self.CONN.lrange(name, start, end)
  59. # 删除列表指定数据
  60. def lrem(self, name, num, value):
  61. """
  62. num:列表方向,删除个数(0:所有)
  63. value:删除的值
  64. """
  65. return self.CONN.lrem(name, num, value)
  66. def get_ttl(self, key):
  67. ttl = self.CONN.ttl(key)
  68. if ttl:
  69. return ttl
  70. else:
  71. return 0
  72. def get_keys(self, key):
  73. keys = self.CONN.keys(key)
  74. if keys:
  75. return keys
  76. else:
  77. return False
  78. def set_ex_data(self, key, val, expire=0):
  79. try:
  80. self.CONN.setex(name=key, time=expire, value=val)
  81. except Exception as e:
  82. return False
  83. else:
  84. return True
  85. def set_hash_data(self, key, kwargs):
  86. self.CONN.hmset(key, kwargs)
  87. def get_hash_data(self, key, file):
  88. value = self.CONN.hmget(key, file)[0]
  89. if value:
  90. return value.decode('utf-8')
  91. else:
  92. return False
  93. def get_all_hash_data(self, key):
  94. return self.CONN.hgetall(key)
  95. def set_persist(self, key):
  96. return self.CONN.persist(key)
  97. def try_lock(self, lock_key, request_id, expire, time_unit_second):
  98. """
  99. 获取分布式锁 原子性
  100. :param lock_key: 锁的key
  101. :param request_id: 请求id
  102. :param expire: 锁过期时间
  103. :param time_unit_second: 时间单位(秒)
  104. :return: True or False
  105. """
  106. try:
  107. # 使用set命令尝试获取锁,并设置nx=True
  108. result = self.CONN.set(lock_key, request_id, ex=time_unit_second * expire, nx=True)
  109. return result is not None
  110. except Exception as e:
  111. print("redis lock error.", e)
  112. return False
  113. def release_lock(self, lock_key, request_id):
  114. """
  115. 释放锁
  116. :param lock_key: 锁的key
  117. :param request_id: 请求id
  118. :return: True or False
  119. """
  120. try:
  121. # 使用Lua脚本来释放锁,避免在执行脚本时发生异常导致锁无法释放
  122. lua_script = """
  123. if redis.call('get', KEYS[1]) == ARGV[1] then
  124. return redis.call('del', KEYS[1])
  125. else
  126. return 0
  127. end
  128. """
  129. result = self.CONN.eval(lua_script, 1, lock_key, request_id)
  130. return result == 1
  131. except Exception as e:
  132. print("redis unlock error.", e)
  133. return False
  134. def incr(self, key, amount=1, ttl=0):
  135. """
  136. 增加计数器的值
  137. :param key: 键名,用于存储计数器的 Redis 键
  138. :param amount: 增加的数量,默认为 1
  139. :param ttl: 键的过期时间(秒)
  140. :return: 更新后的计数值,若发生异常则返回 False
  141. """
  142. try:
  143. # 增加计数器
  144. result = self.CONN.incrby(key, amount)
  145. # 设置过期时间
  146. if ttl > 0:
  147. self.CONN.expire(key, ttl)
  148. return result
  149. except Exception as e:
  150. print(repr(e))
  151. return False
  152. def hash_field_increment(self, key, field, val=1, ttl=0):
  153. """
  154. 哈希表中字段增量
  155. :param key: redis的key
  156. :param field: 哈希表字段
  157. :param val: 增量
  158. :param ttl: 键的过期时间(秒)
  159. :return: 成功返回True 异常返回 False
  160. """
  161. try:
  162. # 增加哈希表中指定字段的值
  163. self.CONN.hincrby(key, field, val)
  164. # 如果 ttl 大于 0,则设置过期时间(单位:秒)
  165. if ttl > 0:
  166. self.CONN.expire(key, ttl)
  167. return True
  168. except Exception as e:
  169. # 发生异常时打印错误信息,便于调试
  170. print(f"增值或设置过期时间时发生错误: {repr(e)}")
  171. return False
  172. def cleanup_hash_fields(self, key, field):
  173. """
  174. 清理哈希表字段
  175. :param key: redis的key
  176. :param field: 字段名
  177. :return: None
  178. """
  179. try:
  180. self.CONN.hdel(key, field)
  181. return True
  182. except Exception as e:
  183. print(f"清理过期字段时发生错误: {repr(e)}")
  184. return False