db_helper.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. import traceback
  2. import time
  3. import redis
  4. from config import set_config
  5. from log import Log
  6. config_ = set_config()
  7. log_ = Log()
  8. conn_redis = None
  9. class RedisHelper(object):
  10. def __init__(self, params=None, redis_info=config_.REDIS_INFO):
  11. """
  12. 初始化redis连接信息
  13. redis_info: redis连接信息, 格式:dict, {'host': '', 'port': '', 'password': ''}
  14. """
  15. self.redis_info = redis_info
  16. self.host = redis_info['host']
  17. self.port = redis_info['port']
  18. self.password = redis_info['password']
  19. self.params = params
  20. def connect(self):
  21. """
  22. 连接redis
  23. :return: conn
  24. """
  25. global conn_redis
  26. if conn_redis is None:
  27. pool = redis.ConnectionPool(host=self.host,
  28. port=self.port,
  29. password=self.password,
  30. decode_responses=True)
  31. conn = redis.Redis(connection_pool=pool)
  32. conn_redis = conn
  33. return conn_redis
  34. def key_exists(self, key_name):
  35. """
  36. 判断key是否存在
  37. :param key_name: key
  38. :return: 存在-True, 不存在-False
  39. """
  40. # start_time = time.time()
  41. conn = self.connect()
  42. res = conn.exists(key_name)
  43. # if self.params is not None:
  44. # log_.info({
  45. # 'logTimestamp': int(time.time() * 1000),
  46. # 'request_id': self.params.request_id,
  47. # 'operation': 'get_data_from_redis',
  48. # 'executeTime': (time.time() - start_time) * 1000
  49. # })
  50. return res
  51. def del_keys(self, key_name):
  52. """
  53. 删除key
  54. :param key_name: key
  55. :return: None
  56. """
  57. conn = self.connect()
  58. conn.delete(key_name)
  59. def get_data_from_redis(self, key_name):
  60. """
  61. 读取redis中的数据
  62. :param key_name: key
  63. :return: data
  64. """
  65. # start_time = time.time()
  66. conn = self.connect()
  67. if not conn.exists(key_name):
  68. # key不存在
  69. return None
  70. data = conn.get(key_name)
  71. # if self.params is not None:
  72. # log_.info({
  73. # 'logTimestamp': int(time.time() * 1000),
  74. # 'request_id': self.params.request_id,
  75. # 'operation': 'get_data_from_redis',
  76. # 'executeTime': (time.time() - start_time) * 1000
  77. # })
  78. return data
  79. def set_data_to_redis(self, key_name, value, expire_time=24*3600):
  80. """
  81. 新增数据
  82. :param key_name: key
  83. :param value: 元素的值 videoId
  84. :param expire_time: 过期时间,单位:s,默认1天
  85. :return: None
  86. """
  87. # start_time = time.time()
  88. conn = self.connect()
  89. conn.set(key_name, value, ex=int(expire_time))
  90. # if self.params is not None:
  91. # log_.info({
  92. # 'logTimestamp': int(time.time() * 1000),
  93. # 'request_id': self.params.request_id,
  94. # 'operation': 'set_data_to_redis',
  95. # 'executeTime': (time.time() - start_time) * 1000})
  96. def add_data_with_zset(self, key_name, data, expire_time=7*24*3600):
  97. """
  98. 新增数据,有序set
  99. :param key_name: key
  100. :param data: 元素的值及对应分数 type-dict {value: score}
  101. :param expire_time: 过期时间,单位:s,默认7天,type-int
  102. :return: None
  103. """
  104. # start_time = time.time()
  105. conn = self.connect()
  106. conn.zadd(key_name, data)
  107. # 设置过期时间
  108. conn.expire(key_name, int(expire_time))
  109. # if self.params is not None:
  110. # log_.info({
  111. # 'logTimestamp': int(time.time() * 1000),
  112. # 'request_id': self.params.request_id,
  113. # 'operation': 'add_data_with_zset',
  114. # 'executeTime': (time.time() - start_time) * 1000
  115. # })
  116. def get_data_zset_with_index(self, key_name, start, end, desc=True, with_scores=False):
  117. """
  118. 根据索引位置获取元素的值
  119. :param key_name: key
  120. :param start: 索引起始点 闭区间,包含start
  121. :param end: 索引结束点 闭区间,包含end
  122. :param desc: 分数排序方式,默认从大到小
  123. :param with_scores: 是否获取元素的分数,默认 False,只获取元素的值
  124. :return: data 元素值列表(不包含分数),value(videoId)类型转换为int, 包含分数时不进行类型转换
  125. """
  126. # start_time = time.time()
  127. conn = self.connect()
  128. if not conn.exists(key_name):
  129. return None
  130. data = conn.zrange(key_name, start, end, desc, with_scores)
  131. if with_scores:
  132. data = data
  133. else:
  134. data = [eval(value) for value in data]
  135. # if self.params is not None:
  136. # log_.info({
  137. # 'logTimestamp': int(time.time() * 1000),
  138. # 'request_id': self.params.request_id,
  139. # 'operation': 'get_data_zset_with_index',
  140. # 'executeTime': (time.time() - start_time) * 1000
  141. # })
  142. return data
  143. def get_all_data_from_zset(self, key_name, desc=True, with_scores=False):
  144. """
  145. 获取zset中所有元素的值
  146. :param key_name: key
  147. :param desc: 分数排序方式,默认从大到小
  148. :param with_scores: 是否获取元素的分数,默认 False,只获取元素的值
  149. :return: data 元素值列表(不包含分数),value(videoId)类型转换为int, 包含分数时不进行类型转换
  150. """
  151. conn = self.connect()
  152. if not conn.exists(key_name):
  153. return None
  154. data = []
  155. start = 0
  156. step = 100
  157. while True:
  158. end = start + step - 1
  159. temp = conn.zrange(key_name, start, end, desc, with_scores)
  160. if not temp:
  161. break
  162. data.extend(temp)
  163. start += step
  164. return data
  165. def get_score_with_value(self, key_name, value):
  166. """
  167. 在zset中,根据元素的value获取对应的score
  168. :param key_name: key
  169. :param value: 元素的值
  170. :return: score value对应的score
  171. """
  172. conn = self.connect()
  173. if not conn.exists(key_name):
  174. return None
  175. return conn.zscore(key_name, value)
  176. def get_rank_with_value(self, key_name, value, desc=False):
  177. """
  178. 在zset中,根据元素的value获取对应排名
  179. :param key_name: key
  180. :param value: 元素的值
  181. :param desc: 是否倒序 type-bool 默认:False-按照score从小到大
  182. :return: rank value对应的rank,从0开始,不存在返回None
  183. """
  184. conn = self.connect()
  185. if not conn.exists(key_name):
  186. return None
  187. if desc is True:
  188. return conn.zrevrank(key_name, value)
  189. else:
  190. return conn.zrank(key_name, value)
  191. def update_score_with_value(self, key_name, value, score, expire_time=24*3600):
  192. """
  193. 在zset中,修改元素value对应的score
  194. :param key_name: key
  195. :param value: 元素的值
  196. :param score: value对应的score更新值
  197. :param expire_time: 过期时间,单位:s,默认1天,type-int
  198. """
  199. conn = self.connect()
  200. if conn.exists(key_name):
  201. conn.zadd(key_name, {value: score})
  202. else:
  203. # key不存在时,需设置过期时间
  204. conn.zadd(key_name, {value: score})
  205. conn.expire(key_name, int(expire_time))
  206. def remove_value_from_zset(self, key_name, value):
  207. """
  208. 删除zset中的指定元素
  209. :param key_name: key
  210. :param value: 元素的值
  211. :return: None
  212. """
  213. # start_time = time.time()
  214. conn = self.connect()
  215. res = conn.zrem(key_name, value)
  216. # if self.params is not None:
  217. # log_.info({
  218. # 'logTimestamp': int(time.time() * 1000),
  219. # 'request_id': self.params.request_id,
  220. # 'operation': 'remove_value_from_zset',
  221. # 'executeTime': (time.time() - start_time) * 1000
  222. # })
  223. return res
  224. def get_index_with_data(self, key_name, value):
  225. """
  226. 根据元素的值获取在有序set中的位置,按照分数倒序(从大到小)
  227. :param key_name: key
  228. :param value: 元素的值
  229. :return: idx 位置索引
  230. """
  231. # start_time = time.time()
  232. conn = self.connect()
  233. res = conn.zrevrank(key_name, value)
  234. # if self.params is not None:
  235. # log_.info({
  236. # 'logTimestamp': int(time.time() * 1000),
  237. # 'request_id': self.params.request_id,
  238. # 'operation': 'get_index_with_data',
  239. # 'executeTime': (time.time() - start_time) * 1000
  240. # })
  241. return res
  242. def get_data_from_set(self, key_name):
  243. """
  244. 获取set中的所有数据
  245. :param key_name: key
  246. :return: data
  247. """
  248. # start_time = time.time()
  249. conn = self.connect()
  250. if not conn.exists(key_name):
  251. # key不存在
  252. return None
  253. data = []
  254. cursor = 0
  255. while True:
  256. cur, temp = conn.sscan(key_name, cursor=cursor, count=2000)
  257. data.extend(temp)
  258. if cur == 0:
  259. break
  260. cursor = cur
  261. # if self.params is not None:
  262. # log_.info({
  263. # 'logTimestamp': int(time.time() * 1000),
  264. # 'request_id': self.params.request_id,
  265. # 'operation': 'get_data_from_set',
  266. # 'executeTime': (time.time() - start_time) * 1000
  267. # })
  268. return list(set(data))
  269. def add_data_with_set(self, key_name, values, expire_time=30*60):
  270. """
  271. 新增数据,set
  272. :param key_name: key
  273. :param values: 要添加的元素 类型-tuple
  274. :param expire_time: 过期时间,单位:s,默认0.5小时 type-int
  275. :return: None
  276. """
  277. # start_time = time.time()
  278. conn = self.connect()
  279. conn.sadd(key_name, *values)
  280. # 设置过期时间
  281. conn.expire(key_name, int(expire_time))
  282. # if self.params is not None:
  283. # log_.info({
  284. # 'logTimestamp': int(time.time() * 1000),
  285. # 'request_id': self.params.request_id,
  286. # 'operation': 'add_data_with_set',
  287. # 'executeTime': (time.time() - start_time) * 1000
  288. # })
  289. def data_exists_with_set(self, key_name, value):
  290. """
  291. 判断元素value是否在集合key_name中
  292. :param key_name: key
  293. :param value: 需判断的元素
  294. :return: 存在-True, 不存在-False
  295. """
  296. # start_time = time.time()
  297. conn = self.connect()
  298. res = conn.sismember(key_name, value)
  299. # if self.params is not None:
  300. # log_.info({
  301. # 'logTimestamp': int(time.time() * 1000),
  302. # 'request_id': self.params.request_id,
  303. # 'operation': 'data_exists_with_set',
  304. # 'executeTime': (time.time() - start_time) * 1000
  305. # })
  306. return res
  307. def get_data_with_count_from_set(self, key_name, count=1):
  308. """
  309. 从set中随机获取元素,并放回
  310. :param key_name: key
  311. :param count: 获取个数, 默认为1
  312. :return:
  313. """
  314. conn = self.connect()
  315. data = conn.srandmember(name=key_name, number=count)
  316. return data
  317. def remove_value_from_set(self, key_name, values):
  318. """
  319. 删除set中的指定元素
  320. :param key_name: key
  321. :param values: 元素的值, 类型-tuple
  322. :return: None
  323. """
  324. # start_time = time.time()
  325. conn = self.connect()
  326. res = conn.srem(key_name, *values)
  327. # if self.params is not None:
  328. # log_.info({
  329. # 'logTimestamp': int(time.time() * 1000),
  330. # 'request_id': self.params.request_id,
  331. # 'operation': 'remove_value_from_set',
  332. # 'executeTime': (time.time() - start_time) * 1000
  333. # })
  334. return res
  335. def decr_key(self, key_name, amount=1, expire_time=30*60):
  336. """
  337. redis自减
  338. :param key_name: key
  339. :param amount: 自减数,默认为1,type-int
  340. :param expire_time: 过期时间,单位:s,默认0.5小时 type-int
  341. :return: None
  342. """
  343. # start_time = time.time()
  344. conn = self.connect()
  345. conn.decr(name=key_name, amount=amount)
  346. conn.expire(key_name, int(expire_time))
  347. # if self.params is not None:
  348. # log_.info({
  349. # 'logTimestamp': int(time.time() * 1000),
  350. # 'request_id': self.params.request_id,
  351. # 'operation': 'decr_key',
  352. # 'executeTime': (time.time() - start_time) * 1000
  353. # })
  354. def incr_key(self, key_name, amount=1, expire_time=30*60):
  355. """
  356. redis自增
  357. :param key_name: key
  358. :param amount: 自增数,默认为1,type-int
  359. :param expire_time: 过期时间,单位:s,默认0.5小时 type-int
  360. :return: None
  361. """
  362. # start_time = time.time()
  363. conn = self.connect()
  364. conn.incr(name=key_name, amount=amount)
  365. conn.expire(key_name, int(expire_time))
  366. # if self.params is not None:
  367. # log_.info({
  368. # 'logTimestamp': int(time.time() * 1000),
  369. # 'request_id': self.params.request_id,
  370. # 'operation': 'incr_key',
  371. # 'executeTime': (time.time() - start_time) * 1000
  372. # })
  373. def setnx_key(self, key_name, value, expire_time=5*60):
  374. """
  375. 当key不存在时,将value塞入key中,key存在时不做操作
  376. :param key_name: key
  377. :param value: value
  378. :return: 过期时间,单位:s,默认5分钟 type-int
  379. """
  380. # start_time = time.time()
  381. conn = self.connect()
  382. conn.setnx(name=key_name, value=value)
  383. conn.expire(name=key_name, time=int(expire_time))
  384. def get_batch_key(self, name_list):
  385. conn = self.connect()
  386. res = conn.mget(name_list)
  387. return res
  388. def mget(self, keys):
  389. conn = self.connect()
  390. data = conn.mget(keys=keys)
  391. return data
  392. if __name__ == '__main__':
  393. redis_helper = RedisHelper()
  394. key_name = f"previewed:videos:5:aan7"
  395. res = redis_helper.get_data_with_count_from_set(
  396. key_name=key_name,
  397. count=20)
  398. print(res)
  399. res1 = redis_helper.remove_value_from_set(key_name=key_name, values=tuple({'2881413'}))
  400. print(res1)
  401. res = redis_helper.get_data_with_count_from_set(
  402. key_name=key_name,
  403. count=20)
  404. print(res)