mdbq 4.0.110__py3-none-any.whl → 4.0.111__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mdbq might be problematic. Click here for more details.

mdbq/__version__.py CHANGED
@@ -1 +1 @@
1
- VERSION = '4.0.110'
1
+ VERSION = '4.0.111'
mdbq/redis/redis_cache.py CHANGED
@@ -73,6 +73,64 @@ class MySQLDataEncoder(json.JSONEncoder):
73
73
  return super().default(obj)
74
74
 
75
75
 
76
+ class SmartTTLConfig:
77
+ """智能TTL配置策略"""
78
+
79
+ # TTL策略映射表(秒)
80
+ TTL_STRATEGIES = {
81
+ # 数据库相关缓存
82
+ 'sycm_database': 1800, # 数据库列表:30分钟
83
+ 'sycm_tables': 1200, # 表列表:20分钟
84
+ 'sycm_table_data': 300, # 表数据:5分钟
85
+
86
+ # 用户会话相关
87
+ 'user_session': 3600, # 用户会话:1小时
88
+ 'user_info': 1800, # 用户信息:30分钟
89
+
90
+ # 静态配置
91
+ 'static_config': 86400, # 静态配置:24小时
92
+ 'system_config': 43200, # 系统配置:12小时
93
+
94
+ # API相关
95
+ 'api_response': 600, # API响应:10分钟
96
+ 'api_cache': 900, # API缓存:15分钟
97
+
98
+ # 临时数据
99
+ 'temp_data': 300, # 临时数据:5分钟
100
+ 'short_cache': 60, # 短期缓存:1分钟
101
+ }
102
+
103
+ @classmethod
104
+ def get_ttl(cls, namespace: str, default: int = 3600) -> int:
105
+ """
106
+ 根据命名空间获取对应的TTL值
107
+
108
+ Args:
109
+ namespace: 缓存命名空间
110
+ default: 默认TTL值(秒)
111
+
112
+ Returns:
113
+ int: TTL值(秒)
114
+ """
115
+ return cls.TTL_STRATEGIES.get(namespace, default)
116
+
117
+ @classmethod
118
+ def add_strategy(cls, namespace: str, ttl: int):
119
+ """
120
+ 添加新的TTL策略
121
+
122
+ Args:
123
+ namespace: 命名空间
124
+ ttl: TTL值(秒)
125
+ """
126
+ cls.TTL_STRATEGIES[namespace] = ttl
127
+
128
+ @classmethod
129
+ def get_all_strategies(cls) -> Dict[str, int]:
130
+ """获取所有TTL策略"""
131
+ return cls.TTL_STRATEGIES.copy()
132
+
133
+
76
134
  class CacheConfig:
77
135
  """缓存系统配置类"""
78
136
 
@@ -98,6 +156,10 @@ class CacheConfig:
98
156
  self.max_value_size = 1024 * 1024 # 1MB
99
157
  self.batch_size = 100
100
158
 
159
+ # 热点键配置
160
+ self.max_hot_keys = 1000 # 最大热点键数量
161
+ self.hot_keys_cleanup_threshold = 800 # 热点键清理阈值
162
+
101
163
  # MySQL数据库配置
102
164
  self.db_name = db_name
103
165
  self.table_name = table_name
@@ -254,6 +316,20 @@ class SmartCacheSystem:
254
316
  """记录热点键"""
255
317
  cache_key = self._generate_cache_key(key, namespace)
256
318
  with self.hot_keys_lock:
319
+ # 检查是否需要清理热点键(防止内存泄漏)
320
+ if len(self.hot_keys) >= self.config.hot_keys_cleanup_threshold:
321
+ # 保留访问次数最高的键,移除访问次数最少的键
322
+ sorted_keys = sorted(self.hot_keys.items(), key=lambda x: x[1], reverse=True)
323
+ # 保留前600个热点键,为新键留出空间
324
+ self.hot_keys = dict(sorted_keys[:600])
325
+
326
+ self.logger.info("热点键内存清理", {
327
+ '清理前数量': len(sorted_keys),
328
+ '清理后数量': len(self.hot_keys),
329
+ '清理阈值': self.config.hot_keys_cleanup_threshold
330
+ })
331
+
332
+ # 记录或更新热点键访问次数
257
333
  self.hot_keys[cache_key] = self.hot_keys.get(cache_key, 0) + 1
258
334
 
259
335
  def get(self, key: str, namespace: str = "", default=None) -> Any:
@@ -290,12 +366,15 @@ class SmartCacheSystem:
290
366
  return default
291
367
 
292
368
  def set(self, key: str, value: Any, ttl: int = None, namespace: str = "") -> bool:
293
- """设置缓存值"""
369
+ """设置缓存值 - 支持智能TTL策略"""
294
370
  start_time = time.time()
295
371
 
296
372
  try:
297
373
  cache_key = self._generate_cache_key(key, namespace)
298
- ttl = ttl or self.config.default_ttl
374
+
375
+ # 使用智能TTL策略
376
+ if ttl is None:
377
+ ttl = SmartTTLConfig.get_ttl(namespace, self.config.default_ttl)
299
378
 
300
379
  # 序列化值
301
380
  if isinstance(value, (dict, list, tuple)):
@@ -313,6 +392,15 @@ class SmartCacheSystem:
313
392
  response_time = (time.time() - start_time) * 1000
314
393
 
315
394
  self._record_operation('sets', response_time)
395
+
396
+ # 记录TTL策略使用情况
397
+ if namespace and ttl != self.config.default_ttl:
398
+ self.logger.debug("使用智能TTL策略", {
399
+ 'namespace': namespace,
400
+ 'ttl': ttl,
401
+ 'key': key[:50] + "..." if len(key) > 50 else key
402
+ })
403
+
316
404
  return bool(result)
317
405
 
318
406
  except Exception as e:
@@ -532,12 +620,23 @@ class SmartCacheSystem:
532
620
  self.logger.error(f"提交统计数据到MySQL失败: {e}")
533
621
 
534
622
  def _cleanup_hot_keys(self):
535
- """清理热点键统计(保留访问次数最高的1000个)"""
623
+ """清理热点键统计 """
536
624
  with self.hot_keys_lock:
537
- if len(self.hot_keys) > 1000:
538
- # 保留访问次数最高的1000个键
625
+ current_count = len(self.hot_keys)
626
+
627
+ # 如果热点键数量超过最大限制,进行清理
628
+ if current_count > self.config.max_hot_keys:
629
+ # 保留访问次数最高的键
539
630
  sorted_keys = sorted(self.hot_keys.items(), key=lambda x: x[1], reverse=True)
540
- self.hot_keys = dict(sorted_keys[:1000])
631
+ # 保留80%的热点键
632
+ keep_count = int(self.config.max_hot_keys * 0.8)
633
+ self.hot_keys = dict(sorted_keys[:keep_count])
634
+
635
+ self.logger.info("定期热点键清理", {
636
+ '清理前数量': current_count,
637
+ '清理后数量': len(self.hot_keys),
638
+ '保留比例': '80%'
639
+ })
541
640
 
542
641
  def _cleanup_expired_mysql_data(self):
543
642
  """清理过期的MySQL统计数据"""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: mdbq
3
- Version: 4.0.110
3
+ Version: 4.0.111
4
4
  Home-page: https://pypi.org/project/mdbq
5
5
  Author: xigua,
6
6
  Author-email: 2587125111@qq.com
@@ -1,5 +1,5 @@
1
1
  mdbq/__init__.py,sha256=Il5Q9ATdX8yXqVxtP_nYqUhExzxPC_qk_WXQ_4h0exg,16
2
- mdbq/__version__.py,sha256=iklgoo0dwUOPXd5UdfLVLjIut4R-avmlkGfuFD8UJGs,19
2
+ mdbq/__version__.py,sha256=nKcO0o5cZBWmqPghn8vvDzV6hZj4cC8f1ESFBAKaOmA,19
3
3
  mdbq/auth/__init__.py,sha256=pnPMAt63sh1B6kEvmutUuro46zVf2v2YDAG7q-jV_To,24
4
4
  mdbq/auth/auth_backend.py,sha256=ZxKRXPXa2t9ngRZEXKM72MzcMvN-0OtiVDOhZRTrm3w,85948
5
5
  mdbq/auth/rate_limiter.py,sha256=1m_Paxp8pDNpmyoFGRpFMVOJpbmeIvfVcfiQ2oH72qM,32850
@@ -26,7 +26,7 @@ mdbq/pbix/pbix_refresh.py,sha256=JUjKW3bNEyoMVfVfo77UhguvS5AWkixvVhDbw4_MHco,239
26
26
  mdbq/pbix/refresh_all.py,sha256=OBT9EewSZ0aRS9vL_FflVn74d4l2G00wzHiikCC4TC0,5926
27
27
  mdbq/redis/__init__.py,sha256=YtgBlVSMDphtpwYX248wGge1x-Ex_mMufz4-8W0XRmA,12
28
28
  mdbq/redis/getredis.py,sha256=vpBuNc22uj9Vr-_Dh25_wpwWM1e-072EAAIBdB_IpL0,23494
29
- mdbq/redis/redis_cache.py,sha256=vu0eJ063iXngm_C1h6NAkaYS69PSDT7gjjJed006hIc,27044
29
+ mdbq/redis/redis_cache.py,sha256=OxtbqHDRO2ko8VS6KkwtqJgPuOFsWvnzIyMIWasnmps,30719
30
30
  mdbq/route/__init__.py,sha256=BT_dAY7V-U2o72bevq1B9Mq9QA7GodwtkxyLNdGaoE8,22
31
31
  mdbq/route/analytics.py,sha256=dngj5hVwKddEUy59nSYbOoJ9C7OVrtCmCkvW6Uj9RYM,28097
32
32
  mdbq/route/monitor.py,sha256=7gLyeq7TqnbhPwhUw0dg-hw9-0OWeKoMdMhcANSDGVs,42255
@@ -34,7 +34,7 @@ mdbq/route/routes.py,sha256=QVGfTvDgu0CpcKCvk1ra74H8uojgqTLUav1fnVAqLEA,29433
34
34
  mdbq/selenium/__init__.py,sha256=AKzeEceqZyvqn2dEDoJSzDQnbuENkJSHAlbHAD0u0ZI,10
35
35
  mdbq/selenium/get_driver.py,sha256=1NTlVUE6QsyjTrVVVqTO2LOnYf578ccFWlWnvIXGtic,20903
36
36
  mdbq/spider/__init__.py,sha256=RBMFXGy_jd1HXZhngB2T2XTvJqki8P_Fr-pBcwijnew,18
37
- mdbq-4.0.110.dist-info/METADATA,sha256=SExR69CN7vO5WwGP6xGeE6HxE5Uw-VoB2CFoUs0hZu8,365
38
- mdbq-4.0.110.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
39
- mdbq-4.0.110.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
40
- mdbq-4.0.110.dist-info/RECORD,,
37
+ mdbq-4.0.111.dist-info/METADATA,sha256=fyVLMYRQ4ArdtViITdjLvQtRlQLtT_lWomGcFhMYzAo,365
38
+ mdbq-4.0.111.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
39
+ mdbq-4.0.111.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
40
+ mdbq-4.0.111.dist-info/RECORD,,
File without changes