check_video_limit_distribute.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import datetime
  2. import numpy as np
  3. from config import set_config
  4. from log import Log
  5. from utils import RedisHelper
  6. config_, _ = set_config()
  7. log_ = Log()
  8. redis_helper = RedisHelper()
  9. def update_limit_video_score(initial_videos, key_name):
  10. """
  11. 调整限流视频的分数: 将视频移至所在列表的中位数之后,多个视频时,按照原本的顺序进行排列
  12. :param initial_videos: 视频列表及score type-dict, {videoId: score, ...}
  13. :param key_name: 视频列表对应的key
  14. :return:
  15. """
  16. if not initial_videos:
  17. return
  18. # 获取当前限流视频
  19. data = redis_helper.get_data_from_redis(key_name=config_.KEY_NAME_PREFIX_LIMIT_VIDEOS)
  20. if data is None:
  21. return
  22. # 获取限流视频对应的score
  23. limit_video_initial_score = []
  24. for video in eval(data):
  25. video_id = int(video[0])
  26. initial_score = initial_videos.get(video_id, None)
  27. if initial_score is not None:
  28. limit_video_initial_score.append((video_id, initial_score))
  29. log_.info(f"limit_video_initial_score = {limit_video_initial_score}")
  30. if len(limit_video_initial_score) == 0:
  31. return
  32. # 获取原始列表的分数的中位数
  33. initial_video_score_list = sorted([val for key, val in initial_videos.items()], reverse=False)
  34. media_score = np.median(initial_video_score_list)
  35. # 取中位数后一位
  36. if len(initial_video_score_list) % 2 == 0:
  37. temp_index = len(initial_video_score_list)//2
  38. else:
  39. temp_index = len(initial_video_score_list) // 2 + 1
  40. if len(initial_video_score_list) > 1:
  41. temp_score = initial_video_score_list[temp_index]
  42. else:
  43. temp_score = 0
  44. # 对限流视频score进行调整
  45. limit_video_final_score = {}
  46. limit_video_initial_score.sort(key=lambda x: x[1], reverse=True)
  47. limit_video_id_list = []
  48. for video_id, initial_score in limit_video_initial_score:
  49. if initial_score > media_score:
  50. limit_video_id_list.append(video_id)
  51. if len(limit_video_id_list) > 0:
  52. limit_score_step = (temp_score - media_score) / (len(limit_video_id_list) + 1)
  53. for i, video_id in enumerate(limit_video_id_list):
  54. final_score = media_score - limit_score_step * (i + 1)
  55. limit_video_final_score[int(video_id)] = final_score
  56. log_.info(f"media_score = {media_score}, temp_score = {temp_score}, "
  57. f"limit_video_final_score = {limit_video_final_score}")
  58. # 更新限流视频的score
  59. if len(limit_video_final_score) == 0:
  60. return
  61. redis_helper.add_data_with_zset(key_name=key_name, data=limit_video_final_score)
  62. def check_videos_distribute():
  63. """
  64. 检查当前限流视频分发数
  65. :return: stop_distribute_video_id_list
  66. """
  67. # 获取当前限流视频及最大分发数
  68. data = redis_helper.get_data_from_redis(key_name=config_.KEY_NAME_PREFIX_LIMIT_VIDEOS)
  69. if data is None:
  70. return []
  71. # 判断是否已超分发
  72. stop_distribute_video_id_list = []
  73. for video_id, max_distribute_count in eval(data):
  74. distributed_count = redis_helper.get_data_from_redis(
  75. key_name=f"{config_.KEY_NAME_PREFIX_LIMIT_VIDEO_DISTRIBUTE_COUNT}{video_id}"
  76. )
  77. if distributed_count is None:
  78. continue
  79. if int(distributed_count) >= int(max_distribute_count):
  80. stop_distribute_video_id_list.append(int(video_id))
  81. return stop_distribute_video_id_list
  82. def check_region_videos():
  83. """检查限流视频分发数"""
  84. # 获取当前日期
  85. now_date = datetime.datetime.today()
  86. # 获取当前所在小时
  87. now_h = datetime.datetime.now().hour
  88. log_.info(f'now_date = {now_date}, now_h = {now_h}.')
  89. # 获取已超分发视频
  90. stop_distribute_video_id_list = check_videos_distribute()
  91. log_.info(f"stop_distribute_video_id_list = {stop_distribute_video_id_list}, "
  92. f"count = {len(stop_distribute_video_id_list)}")
  93. if len(stop_distribute_video_id_list) == 0:
  94. return
  95. # 对已超分发的视频进行移除
  96. region_code_list = [code for region, code in config_.REGION_CODE.items()]
  97. rule_params = config_.RULE_PARAMS_REGION
  98. for region in region_code_list:
  99. log_.info(f"region = {region}")
  100. for key, value in rule_params.items():
  101. log_.info(f"rule = {key}, param = {value}")
  102. # 将已超分发视频加入到地域小时级线上过滤应用列表中
  103. redis_helper.add_data_with_set(
  104. key_name=f"{config_.REGION_H_VIDEO_FILER}{region}.{key}",
  105. values=stop_distribute_video_id_list,
  106. expire_time=2 * 3600
  107. )
  108. # 将已超分发视频加入到地域分组24h的数据线上过滤应用列表中
  109. redis_helper.add_data_with_set(
  110. key_name=f"{config_.REGION_H_VIDEO_FILER_24H}{region}.{key}",
  111. values=stop_distribute_video_id_list,
  112. expire_time=2 * 3600
  113. )
  114. # 将已超分发视频加入到不区分相对24h线上过滤应用列表中
  115. redis_helper.add_data_with_set(
  116. key_name=f"{config_.H_VIDEO_FILER_24H}{region}.{key}",
  117. values=stop_distribute_video_id_list,
  118. expire_time=2 * 3600
  119. )
  120. # 将已超分发视频 移除 大列表
  121. key_name = f"{config_.RECALL_KEY_NAME_PREFIX_DUP_REGION_H}{region}.{key}." \
  122. f"{datetime.datetime.strftime(now_date, '%Y%m%d')}.{now_h}"
  123. if not redis_helper.key_exists(key_name=key_name):
  124. if now_h == 0:
  125. redis_date = now_date - datetime.timedelta(days=1)
  126. redis_h = 23
  127. else:
  128. redis_date = now_date
  129. redis_h = now_h - 1
  130. key_name = f"{config_.RECALL_KEY_NAME_PREFIX_DUP_REGION_H}{region}.{key}." \
  131. f"{datetime.datetime.strftime(redis_date, '%Y%m%d')}.{redis_h}"
  132. redis_helper.remove_value_from_zset(key_name=key_name, value=stop_distribute_video_id_list)
  133. log_.info(f"region = {region} videos check end!")
  134. log_.info("region_h videos check end!")
  135. # 将已超分发视频 移除 原始大列表
  136. key_name = f"{config_.RECALL_KEY_NAME_PREFIX}{datetime.datetime.strftime(now_date, '%Y%m%d')}"
  137. if not redis_helper.key_exists(key_name=key_name):
  138. redis_date = now_date - datetime.timedelta(days=1)
  139. key_name = f"{config_.RECALL_KEY_NAME_PREFIX}{datetime.datetime.strftime(redis_date, '%Y%m%d')}"
  140. redis_helper.remove_value_from_zset(key_name=key_name, value=stop_distribute_video_id_list)
  141. if __name__ == '__main__':
  142. check_region_videos()