mdbq 4.0.106__tar.gz → 4.0.108__tar.gz

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.

Files changed (45) hide show
  1. {mdbq-4.0.106 → mdbq-4.0.108}/PKG-INFO +1 -1
  2. mdbq-4.0.108/mdbq/__version__.py +1 -0
  3. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/redis/redis_cache.py +116 -48
  4. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq.egg-info/PKG-INFO +1 -1
  5. mdbq-4.0.106/mdbq/__version__.py +0 -1
  6. {mdbq-4.0.106 → mdbq-4.0.108}/README.txt +0 -0
  7. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/__init__.py +0 -0
  8. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/auth/__init__.py +0 -0
  9. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/auth/auth_backend.py +0 -0
  10. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/auth/rate_limiter.py +0 -0
  11. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/js/__init__.py +0 -0
  12. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/js/jc.py +0 -0
  13. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/log/__init__.py +0 -0
  14. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/log/mylogger.py +0 -0
  15. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/myconf/__init__.py +0 -0
  16. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/myconf/myconf.py +0 -0
  17. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/mysql/__init__.py +0 -0
  18. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/mysql/deduplicator.py +0 -0
  19. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/mysql/mysql.py +0 -0
  20. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/mysql/s_query.py +0 -0
  21. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/mysql/unique_.py +0 -0
  22. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/mysql/uploader.py +0 -0
  23. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/other/__init__.py +0 -0
  24. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/other/download_sku_picture.py +0 -0
  25. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/other/error_handler.py +0 -0
  26. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/other/otk.py +0 -0
  27. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/other/pov_city.py +0 -0
  28. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/other/ua_sj.py +0 -0
  29. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/pbix/__init__.py +0 -0
  30. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/pbix/pbix_refresh.py +0 -0
  31. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/pbix/refresh_all.py +0 -0
  32. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/redis/__init__.py +0 -0
  33. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/redis/getredis.py +0 -0
  34. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/route/__init__.py +0 -0
  35. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/route/analytics.py +0 -0
  36. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/route/monitor.py +0 -0
  37. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/route/routes.py +0 -0
  38. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/selenium/__init__.py +0 -0
  39. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/selenium/get_driver.py +0 -0
  40. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq/spider/__init__.py +0 -0
  41. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq.egg-info/SOURCES.txt +0 -0
  42. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq.egg-info/dependency_links.txt +0 -0
  43. {mdbq-4.0.106 → mdbq-4.0.108}/mdbq.egg-info/top_level.txt +0 -0
  44. {mdbq-4.0.106 → mdbq-4.0.108}/setup.cfg +0 -0
  45. {mdbq-4.0.106 → mdbq-4.0.108}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: mdbq
3
- Version: 4.0.106
3
+ Version: 4.0.108
4
4
  Home-page: https://pypi.org/project/mdbq
5
5
  Author: xigua,
6
6
  Author-email: 2587125111@qq.com
@@ -0,0 +1 @@
1
+ VERSION = '4.0.108'
@@ -35,44 +35,57 @@ logger = mylogger.MyLogger(
35
35
  class CacheConfig:
36
36
  """缓存系统配置类"""
37
37
 
38
- # TTL配置(秒)
39
- DEFAULT_TTL = 3600 # 1小时
40
- SHORT_TTL = 300 # 5分钟
41
- MEDIUM_TTL = 1800 # 30分钟
42
- LONG_TTL = 7200 # 2小时
43
- VERY_LONG_TTL = 86400 # 24小时
44
-
45
- # 缓存键前缀
46
- CACHE_PREFIX = "smart_cache:"
47
- STATS_PREFIX = "cache_stats:"
48
- LOCK_PREFIX = "cache_lock:"
49
-
50
- # 统计配置
51
- STATS_INTERVAL = 300 # 统计间隔(秒)
52
- STATS_RETENTION = 7 # 统计数据保留天数
53
-
54
- # 性能配置
55
- MAX_KEY_LENGTH = 250
56
- MAX_VALUE_SIZE = 1024 * 1024 # 1MB
57
- BATCH_SIZE = 100
58
-
59
- # 数据库配置
60
- DB_NAME = "redis统计"
61
- TABLE_NAME = "dpflask路由分析"
62
-
63
- # 锁配置
64
- LOCK_TIMEOUT = 30 # 分布式锁超时时间
65
- LOCK_RETRY_DELAY = 0.1 # 锁重试延迟
38
+ def __init__(self, db_name: str = "redis统计", table_name: str = "dpflask路由分析"):
39
+ # TTL配置(秒)
40
+ self.default_ttl = 3600 # 1小时
41
+ self.short_ttl = 300 # 5分钟
42
+ self.medium_ttl = 1800 # 30分钟
43
+ self.long_ttl = 7200 # 2小时
44
+ self.very_long_ttl = 86400 # 24小时
45
+
46
+ # 缓存键前缀
47
+ self.cache_prefix = "smart_cache:"
48
+ self.stats_prefix = "cache_stats:"
49
+ self.lock_prefix = "cache_lock:"
50
+
51
+ # 统计配置
52
+ self.stats_interval = 1800 # 统计间隔(秒), 自动提交统计信息到MySQL的间隔
53
+ self.stats_retention = 7 # MySQL统计数据保留天数,超过此天数的数据将被自动删除
54
+
55
+ # 性能配置
56
+ self.max_key_length = 250
57
+ self.max_value_size = 1024 * 1024 # 1MB
58
+ self.batch_size = 100
59
+
60
+ # MySQL数据库配置
61
+ self.db_name = db_name
62
+ self.table_name = table_name
63
+
64
+ # 锁配置
65
+ self.lock_timeout = 30 # 分布式锁超时时间
66
+ self.lock_retry_delay = 0.1 # 锁重试延迟
66
67
 
67
68
 
68
69
  class SmartCacheSystem:
69
70
  """智能缓存系统核心类"""
70
71
 
71
- def __init__(self, redis_client: redis.Redis, mysql_pool=None, instance_name: str = "default"):
72
+ def __init__(self, redis_client: redis.Redis, mysql_pool=None, instance_name: str = "default",
73
+ config: CacheConfig = None, db_name: str = None, table_name: str = None):
72
74
  self.redis_client = redis_client
73
75
  self.mysql_pool = mysql_pool
74
76
  self.instance_name = instance_name
75
- self.config = CacheConfig()
77
+
78
+ # 配置优先级:传入的config > 自定义db_name/table_name > 默认配置
79
+ if config:
80
+ self.config = config
81
+ elif db_name or table_name:
82
+ self.config = CacheConfig(
83
+ db_name=db_name or "redis统计",
84
+ table_name=table_name or "dpflask路由分析"
85
+ )
86
+ else:
87
+ self.config = CacheConfig()
88
+
76
89
  self.logger = logger
77
90
 
78
91
  # 统计数据
@@ -126,13 +139,14 @@ class SmartCacheSystem:
126
139
  try:
127
140
  with connection.cursor() as cursor:
128
141
  # 创建数据库
129
- cursor.execute(f"CREATE DATABASE IF NOT EXISTS `{self.config.DB_NAME}` DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci")
130
- cursor.execute(f"USE `{self.config.DB_NAME}`")
142
+ cursor.execute(f"CREATE DATABASE IF NOT EXISTS `{self.config.db_name}` DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci")
143
+ cursor.execute(f"USE `{self.config.db_name}`")
131
144
 
132
145
  # 创建表(MySQL 8.4+兼容语法)
133
146
  create_table_sql = f"""
134
- CREATE TABLE IF NOT EXISTS `{self.config.TABLE_NAME}` (
147
+ CREATE TABLE IF NOT EXISTS `{self.config.table_name}` (
135
148
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
149
+ `日期` date NOT NULL COMMENT '统计日期',
136
150
  `统计时间` datetime NOT NULL COMMENT '统计时间',
137
151
  `时间段` varchar(20) NOT NULL COMMENT '时间段标识',
138
152
  `缓存命中数` bigint DEFAULT 0 COMMENT '缓存命中次数',
@@ -152,6 +166,7 @@ class SmartCacheSystem:
152
166
  `创建时间` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
153
167
  `更新时间` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录更新时间',
154
168
  PRIMARY KEY (`id`),
169
+ KEY `idx_stats_date` (`日期`),
155
170
  KEY `idx_stats_time` (`统计时间`),
156
171
  KEY `idx_time_period` (`时间段`),
157
172
  KEY `idx_hit_rate` (`命中率`),
@@ -164,8 +179,8 @@ class SmartCacheSystem:
164
179
  connection.commit()
165
180
 
166
181
  self.logger.info("MySQL数据库表初始化成功", {
167
- 'database': self.config.DB_NAME,
168
- 'table': self.config.TABLE_NAME
182
+ 'database': self.config.db_name,
183
+ 'table': self.config.table_name
169
184
  })
170
185
  return True
171
186
 
@@ -179,8 +194,8 @@ class SmartCacheSystem:
179
194
  def _generate_cache_key(self, key: str, namespace: str = "") -> str:
180
195
  """生成缓存键"""
181
196
  if namespace:
182
- return f"{self.config.CACHE_PREFIX}{namespace}:{key}"
183
- return f"{self.config.CACHE_PREFIX}{key}"
197
+ return f"{self.config.cache_prefix}{namespace}:{key}"
198
+ return f"{self.config.cache_prefix}{key}"
184
199
 
185
200
  def _record_operation(self, operation: str, response_time: float = 0):
186
201
  """记录操作统计"""
@@ -239,7 +254,7 @@ class SmartCacheSystem:
239
254
 
240
255
  try:
241
256
  cache_key = self._generate_cache_key(key, namespace)
242
- ttl = ttl or self.config.DEFAULT_TTL
257
+ ttl = ttl or self.config.default_ttl
243
258
 
244
259
  # 序列化值
245
260
  if isinstance(value, (dict, list, tuple)):
@@ -248,7 +263,7 @@ class SmartCacheSystem:
248
263
  serialized_value = str(value)
249
264
 
250
265
  # 检查值大小
251
- if len(serialized_value.encode('utf-8')) > self.config.MAX_VALUE_SIZE:
266
+ if len(serialized_value.encode('utf-8')) > self.config.max_value_size:
252
267
  self.logger.warning(f"缓存值过大,跳过设置: {len(serialized_value)} bytes")
253
268
  return False
254
269
 
@@ -300,7 +315,7 @@ class SmartCacheSystem:
300
315
  def clear_namespace(self, namespace: str) -> int:
301
316
  """清除指定命名空间的所有缓存"""
302
317
  try:
303
- pattern = f"{self.config.CACHE_PREFIX}{namespace}:*"
318
+ pattern = f"{self.config.cache_prefix}{namespace}:*"
304
319
  keys = self.redis_client.keys(pattern)
305
320
 
306
321
  if keys:
@@ -389,6 +404,7 @@ class SmartCacheSystem:
389
404
 
390
405
  def _stats_worker(self):
391
406
  """后台统计工作线程"""
407
+ cleanup_counter = 0 # 清理计数器
392
408
  while self._stats_running:
393
409
  try:
394
410
  # 收集统计数据
@@ -400,11 +416,17 @@ class SmartCacheSystem:
400
416
  # 清理过期的热点键统计
401
417
  self._cleanup_hot_keys()
402
418
 
419
+ # 每24次统计周期(约2小时)执行一次过期数据清理
420
+ cleanup_counter += 1
421
+ if cleanup_counter >= 24: # 24 * 300秒 = 2小时
422
+ self._cleanup_expired_mysql_data()
423
+ cleanup_counter = 0
424
+
403
425
  except Exception as e:
404
426
  self.logger.error(f"统计工作线程异常: {e}")
405
427
 
406
428
  # 等待下一个统计间隔
407
- time.sleep(self.config.STATS_INTERVAL)
429
+ time.sleep(self.config.stats_interval)
408
430
 
409
431
  def _submit_stats_to_mysql(self, stats_data: Dict[str, Any]):
410
432
  """提交统计数据到MySQL"""
@@ -416,24 +438,26 @@ class SmartCacheSystem:
416
438
  connection = self.mysql_pool.connection()
417
439
  try:
418
440
  with connection.cursor() as cursor:
419
- cursor.execute(f"USE `{self.config.DB_NAME}`")
441
+ cursor.execute(f"USE `{self.config.db_name}`")
420
442
 
421
443
  # 准备数据
422
444
  now = datetime.now()
445
+ date_str = now.strftime("%Y-%m-%d") # 格式: 2024-10-01
423
446
  time_period = now.strftime("%Y%m%d_%H%M")
424
447
 
425
448
  insert_sql = f"""
426
- INSERT INTO `{self.config.TABLE_NAME}` (
427
- `统计时间`, `时间段`, `缓存命中数`, `缓存未命中数`, `缓存设置数`,
449
+ INSERT INTO `{self.config.table_name}` (
450
+ `日期`, `统计时间`, `时间段`, `缓存命中数`, `缓存未命中数`, `缓存设置数`,
428
451
  `缓存删除数`, `缓存错误数`, `命中率`, `总操作数`, `平均响应时间`,
429
452
  `每秒操作数`, `唯一键数量`, `系统运行时间`, `热点键统计`,
430
453
  `服务器主机`, `实例名称`
431
454
  ) VALUES (
432
- %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s
455
+ %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s
433
456
  )
434
457
  """
435
458
 
436
459
  cursor.execute(insert_sql, (
460
+ date_str,
437
461
  now,
438
462
  time_period,
439
463
  stats_data['hits'],
@@ -474,6 +498,44 @@ class SmartCacheSystem:
474
498
  sorted_keys = sorted(self.hot_keys.items(), key=lambda x: x[1], reverse=True)
475
499
  self.hot_keys = dict(sorted_keys[:1000])
476
500
 
501
+ def _cleanup_expired_mysql_data(self):
502
+ """清理过期的MySQL统计数据"""
503
+ if not self.mysql_pool:
504
+ return
505
+
506
+ try:
507
+ connection = self.mysql_pool.connection()
508
+ try:
509
+ with connection.cursor() as cursor:
510
+ cursor.execute(f"USE `{self.config.db_name}`")
511
+
512
+ # 计算过期时间点
513
+ from datetime import timedelta
514
+ expire_date = datetime.now() - timedelta(days=self.config.stats_retention)
515
+
516
+ # 删除过期数据
517
+ delete_sql = f"""
518
+ DELETE FROM `{self.config.table_name}`
519
+ WHERE `统计时间` < %s
520
+ """
521
+
522
+ cursor.execute(delete_sql, (expire_date,))
523
+ deleted_rows = cursor.rowcount
524
+ connection.commit()
525
+
526
+ if deleted_rows > 0:
527
+ self.logger.info("清理过期MySQL统计数据", {
528
+ 'deleted_rows': deleted_rows,
529
+ 'expire_date': expire_date.strftime('%Y-%m-%d %H:%M:%S'),
530
+ 'retention_days': self.config.stats_retention
531
+ })
532
+
533
+ finally:
534
+ connection.close()
535
+
536
+ except Exception as e:
537
+ self.logger.error(f"清理过期MySQL统计数据失败: {e}")
538
+
477
539
  def shutdown(self):
478
540
  """关闭缓存系统"""
479
541
  self.logger.info("正在关闭缓存系统...")
@@ -516,18 +578,24 @@ class CacheManager:
516
578
  self._initialized = True
517
579
  self.logger = logger
518
580
 
519
- def initialize(self, redis_client: redis.Redis, mysql_pool=None, instance_name: str = "default"):
581
+ def initialize(self, redis_client: redis.Redis, mysql_pool=None, instance_name: str = "default",
582
+ config: CacheConfig = None, db_name: str = None, table_name: str = None):
520
583
  """初始化缓存系统"""
521
584
  try:
522
585
  self.cache_instance = SmartCacheSystem(
523
586
  redis_client=redis_client,
524
587
  mysql_pool=mysql_pool,
525
- instance_name=instance_name
588
+ instance_name=instance_name,
589
+ config=config,
590
+ db_name=db_name,
591
+ table_name=table_name
526
592
  )
527
593
  self.initialization_error = None
528
594
  self.logger.info("缓存管理器初始化成功", {
529
595
  'instance_name': instance_name,
530
- 'mysql_enabled': mysql_pool is not None
596
+ 'mysql_enabled': mysql_pool is not None,
597
+ 'db_name': self.cache_instance.config.db_name,
598
+ 'table_name': self.cache_instance.config.table_name
531
599
  })
532
600
  return self # 支持链式调用
533
601
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: mdbq
3
- Version: 4.0.106
3
+ Version: 4.0.108
4
4
  Home-page: https://pypi.org/project/mdbq
5
5
  Author: xigua,
6
6
  Author-email: 2587125111@qq.com
@@ -1 +0,0 @@
1
- VERSION = '4.0.106'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes