You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
4.1KB

  1. import redis
  2. import os
  3. from config import conf
  4. import uuid
  5. import time
  6. # 定义全局 redis_helper
  7. redis_helper = None
  8. class RedisHelper:
  9. def __init__(self, host='localhost', port=6379, password=None ,db=0):
  10. # 初始化 Redis 连接
  11. self.client = redis.Redis(host=host, port=port,db=db,password=password)
  12. def set_hash(self, hash_key, data, timeout=None):
  13. """添加或更新哈希,并设置有效期"""
  14. self.client.hset(hash_key, mapping=data)
  15. if timeout:
  16. # 设置有效期(单位:秒)
  17. self.client.expire(hash_key, timeout)
  18. def get_hash(self, hash_key):
  19. """获取整个哈希表数据"""
  20. result = self.client.hgetall(hash_key)
  21. # 将字节数据解码成字符串格式返回
  22. return {k.decode('utf-8'): v.decode('utf-8') for k, v in result.items()}
  23. def get_hash_field(self, hash_key, field):
  24. """获取哈希表中的单个字段值"""
  25. result = self.client.hget(hash_key, field)
  26. return result.decode('utf-8') if result else None
  27. def delete_hash(self, hash_key):
  28. """删除整个哈希表"""
  29. self.client.delete(hash_key)
  30. def delete_hash_field(self, hash_key, field):
  31. """删除哈希表中的某个字段"""
  32. self.client.hdel(hash_key, field)
  33. def update_hash_field(self, hash_key, field, value):
  34. """更新哈希表中的某个字段"""
  35. self.client.hset(hash_key, field, value)
  36. def acquire_lock(self, lock_key, expire_time=60, timeout=None):
  37. """
  38. 获取分布式锁。
  39. Args:
  40. lock_key: 锁的键名。
  41. expire_time: 锁的有效时间(秒)。
  42. timeout: 最大等待时间(秒),默认为None表示无限等待。
  43. Returns:
  44. 成功获取锁返回True,否则返回False。
  45. """
  46. identifier = str(uuid.uuid4())
  47. while True:
  48. # 尝试获取锁
  49. if self.client.setnx(lock_key, identifier):
  50. self.client.expire(lock_key, expire_time)
  51. return True
  52. # 检查锁是否存在且未过期
  53. current_value = self.client.get(lock_key)
  54. if not current_value:
  55. continue # 锁不存在,继续尝试获取
  56. # 检查锁是否已过期
  57. ttl = self.client.ttl(lock_key)
  58. if ttl == -2: # 锁已过期
  59. continue
  60. # 如果超时时间设置且已经超出,则返回False
  61. if timeout is not None:
  62. start_time = time.time()
  63. while (time.time() - start_time) < timeout:
  64. time.sleep(0.1)
  65. return self.acquire_lock(lock_key, expire_time, timeout)
  66. else:
  67. # 超时,放弃获取锁
  68. return False
  69. # 等待一段时间后重试
  70. time.sleep(0.1)
  71. def release_lock(self, lock_key):
  72. """
  73. 释放分布式锁。
  74. Args:
  75. lock_key: 锁的键名。
  76. Returns:
  77. 成功释放返回True,否则返回False。
  78. """
  79. script = """
  80. if redis.call("get", KEYS[1]) == ARGV[1] then
  81. return redis.call("del", KEYS[1])
  82. else
  83. return 0
  84. end
  85. """
  86. current_value = self.client.get(lock_key)
  87. if not current_value:
  88. return False
  89. identifier = str(uuid.uuid4()) # 这里应替换为获取锁时使用的标识符
  90. result = self.client.eval(script, [lock_key], [identifier])
  91. return result == 1
  92. def start():
  93. global redis_helper
  94. host=conf().get("redis_host")
  95. port=conf().get("redis_port")
  96. password=conf().get("redis_password")
  97. db=conf().get("redis_db")
  98. redis_helper = RedisHelper(host=host,port=port,password=password,db=db)