crc32稳定哈希

 1 """Sharded MySQL repository: route by user_id, scatter-gather counts."""
 2 
 3 import asyncio
 4 import zlib
 5 
 6 import aiomysql
 7 
 8 from app.config import settings
 9 from app.domain import Action
10 from app.mysql_repo import LikeRepository
11 
12 
13 def shard_of(user_id: int, n: int) -> int:
14     """Stable, cross-process-consistent shard index. NOT Python hash()."""
15     return zlib.crc32(str(user_id).encode()) % n
16 
17 
18 class ShardedLikeRepository:
19     def __init__(self, shards: list[LikeRepository]):
20         self._shards = shards
21         self._n = len(shards)
22 
23     def _for(self, user_id: int) -> LikeRepository:
24         return self._shards[shard_of(user_id, self._n)]
25 
26     async def upsert(self, user_id: int, content_id: int, action: Action) -> None:
27         await self._for(user_id).upsert(user_id, content_id, action)
28 
29     async def get_status(self, user_id: int, content_id: int) -> int | None:
30         return await self._for(user_id).get_status(user_id, content_id)
31 
32     async def get_count(self, content_id: int) -> int:
33         """Scatter-gather: query all shards in parallel, sum."""
34         results = await asyncio.gather(
35             *[s.get_count(content_id) for s in self._shards]
36         )
37         return sum(results)
38 
39 
40 async def build_sharded_repo() -> ShardedLikeRepository:
41     """Build N pools from settings and wrap as a sharded repo."""
42     shards = []
43     for i in range(settings.mysql_shards):
44         pool = await aiomysql.create_pool(
45             host=settings.mysql_host,
46             port=settings.mysql_port + i,
47             user=settings.mysql_user,
48             password=settings.mysql_password,
49             db=settings.mysql_db,
50             autocommit=False,
51         )
52         shards.append(LikeRepository(pool))
53     return ShardedLikeRepository(shards)

 

posted @ 2026-07-30 11:13  Fmaj-7  阅读(7)  评论(0)    收藏  举报