Skip to main content

High-concurrency Redis-backed credential pool SDK.

Project description

credential-pool-sdk

一个基于 Redis 的高并发共享凭证池 SDK。

它的目标不是绑定某个具体业务,而是提供一套可复用的“凭证池基础设施”能力,适合在多进程、多节点环境下统一管理以下对象:

  1. Cookie
  2. JWT
  3. Token
  4. Nonce
  5. Session
  6. 其他需要共享、复用、并发控制的认证凭证

设计目标

本项目聚焦“池能力”,不耦合业务代码,不内置具体站点逻辑。

核心目标:

  1. 通过 pip install 安装使用
  2. 只依赖 Redis 作为共享状态中心
  3. 提供统一的凭证池 API
  4. 支持高并发随机获取
  5. 支持独占获取与归还
  6. 支持失败计数、租约回收、统计查询

适用场景

适合以下场景:

  1. 多个 worker 共享一批 Cookie / JWT
  2. 某些凭证允许被重复并发使用
  3. 某些凭证同一时间只能被一个 worker 独占使用
  4. 多台机器共同消费同一池凭证
  5. 业务项目希望把“凭证共享与并发控制”抽成独立 SDK

架构图

下面这张图描述了 credential-pool-sdk 在业务项目中的典型位置:

flowchart LR
    A[业务 Producer<br/>生成 Cookie / JWT / Token] --> B[credential-pool-sdk]
    C[业务 Consumer 1<br/>Worker / Collector] --> B
    D[业务 Consumer 2<br/>Worker / Service] --> B
    E[业务 Consumer N<br/>多节点实例] --> B

    B --> F[(Redis)]

    subgraph SDK[credential-pool-sdk]
        B1[RedisCredentialPool]
        B2[CredentialItem]
        B3[Lease / Failure / Stats]
    end

    B --- B1
    B --- B2
    B --- B3

架构说明

  1. Producer 负责生成凭证,并调用 SDK 写入池。
  2. Consumer 负责从池中获取凭证,并在使用后回写结果。
  3. SDK 只负责“共享池能力”,不负责业务调度。
  4. Redis 作为多节点之间的共享状态中心。

时序图

下面是“独占获取一个当前未被使用的凭证,并在使用后归还”的典型时序:

sequenceDiagram
    participant Worker as 业务 Worker
    participant SDK as credential-pool-sdk
    participant Redis as Redis
    participant Target as 目标站点

    Worker->>SDK: acquire_available(owner, lease_ttl)
    SDK->>Redis: Lua 原子脚本<br/>从 available 随机取一个 key<br/>写入 lease_owner / lease_expiry
    Redis-->>SDK: 返回 credential key
    SDK->>Redis: HGET items[key]
    Redis-->>SDK: 返回 CredentialItem
    SDK-->>Worker: 返回独占凭证

    Worker->>Target: 使用凭证发起请求
    Target-->>Worker: 返回结果

    alt 成功
        Worker->>SDK: record_success(key)
        SDK->>Redis: HDEL failures[key]
        Worker->>SDK: release(key, owner)
        SDK->>Redis: Lua 原子脚本<br/>删除 lease<br/>放回 available
    else 失败
        Worker->>SDK: record_failure(key)
        SDK->>Redis: HINCRBY failures[key]
        Worker->>SDK: release(key, owner)
        SDK->>Redis: Lua 原子脚本<br/>删除 lease<br/>放回 available
    end

两种获取模式的区别

模式一:共享获取

item = await pool.random_get()

特点:

  1. 同一个凭证可以被多个调用方同时拿到
  2. 不会改变凭证当前可用状态
  3. 适合可共享复用的凭证

模式二:独占获取

leased = await pool.acquire_available(owner="worker-1", lease_ttl=60)

特点:

  1. 同一个凭证同一时间只能被一个调用方持有
  2. 获取后必须通过 release() 归还
  3. 若调用方崩溃,可通过 reclaim_expired_leases() 回收

核心能力

1. 统一对象模型

池中的元素不是裸字符串,而是统一对象,例如:

{
  "key": "jwt:1",
  "value": "token-1",
  "kind": "jwt",
  "status": "active",
  "created_at": 1760000000,
  "updated_at": 1760000000,
  "meta": {}
}

这样后续扩展字段时,不需要改动使用方式。

2. 两种获取模式

本 SDK 提供两种不同的“取凭证”方式。

random_get()

随机获取一个凭证。

特点:

  1. 同一个凭证可以被多个调用方同时取到
  2. 适合“可共享复用”的场景
  3. 例如:某些 JWT、某些无状态 Cookie

acquire_available(owner, lease_ttl)

随机获取一个当前未被占用的凭证,并立即标记为“已被使用”。

特点:

  1. 同一时间,一个凭证只能被一个调用方独占获取
  2. 适合“同一时刻只能单独使用”的场景
  3. 获取后必须通过 release() 归还
  4. 若调用方异常退出,也可以通过过期租约回收

3. 归还凭证

通过:

await pool.release(key, owner="worker-1")

将独占中的凭证重新放回可用池。

4. 基础 CRUD

支持:

  1. 添加单个凭证
  2. 批量添加凭证
  3. 查询单个凭证
  4. 列表查询
  5. 更新凭证
  6. 删除凭证

5. 失败计数

支持:

  1. record_success(key)
  2. record_failure(key)
  3. get_failure_count(key)

适合业务层自行实现失败阈值策略。

6. 租约回收

支持:

await pool.reclaim_expired_leases()

用于回收超时未归还的独占凭证。

7. 统计能力

支持:

  1. 总凭证数
  2. 可用凭证数
  3. 已租约凭证数
  4. 失败计数条目数

安装

pip install credential-pool-sdk

如果是本地开发:

pip install -e .

快速开始

创建连接

from credential_pool_sdk import RedisCredentialPool

pool = RedisCredentialPool.from_url(
    "redis://127.0.0.1:6379/0",
    pool_name="vimeo_jwt",
)

凭证对象示例

from credential_pool_sdk import CredentialItem

item = CredentialItem(
    key="jwt:1",
    value="token-1",
    kind="jwt",
    meta={"source": "producer-a"},
)

添加凭证

from credential_pool_sdk import CredentialItem

await pool.add(
    CredentialItem(
        key="jwt:1",
        value="token-1",
        kind="jwt",
    )
)

随机获取一个可共享凭证

item = await pool.random_get()
if item is not None:
    print(item.key, item.value)

独占获取一个当前未使用凭证

leased = await pool.acquire_available(owner="worker-1", lease_ttl=60)
if leased is not None:
    print("acquired:", leased.key)

归还独占凭证

await pool.release(leased.key, owner="worker-1")

失败计数

await pool.record_failure("jwt:1")
failures = await pool.get_failure_count("jwt:1")
print(failures)

回收超时未归还租约

reclaimed = await pool.reclaim_expired_leases()
print("reclaimed:", reclaimed)

完整示例

import asyncio

from credential_pool_sdk import CredentialItem, RedisCredentialPool


async def main() -> None:
    pool = RedisCredentialPool.from_url(
        "redis://127.0.0.1:6379/0",
        pool_name="vimeo_jwt",
    )

    await pool.add(
        CredentialItem(
            key="jwt:1",
            value="token-1",
            kind="jwt",
        )
    )

    shared_item = await pool.random_get()
    print("shared:", shared_item)

    leased_item = await pool.acquire_available(owner="worker-1", lease_ttl=60)
    print("leased:", leased_item)

    if leased_item is not None:
        await pool.release(leased_item.key, owner="worker-1")

    stats = await pool.stats()
    print(stats)

    await pool.close()


asyncio.run(main())

API 概览

池对象

RedisCredentialPool

主要方法:

  1. add(item)
  2. add_many(items)
  3. get(key)
  4. list(limit=100)
  5. update(key, patch)
  6. remove(key)
  7. random_get()
  8. acquire_available(owner, lease_ttl=60, exclude_keys=None)
  9. release(key, owner=None)
  10. reclaim_expired_leases(now_ts=None)
  11. record_success(key)
  12. record_failure(key, amount=1)
  13. get_failure_count(key)
  14. count()
  15. count_available()
  16. count_leased()
  17. stats()
  18. close()

数据对象

CredentialItem

字段:

  1. key
  2. value
  3. kind
  4. status
  5. created_at
  6. updated_at
  7. meta

统计对象

PoolStats

字段:

  1. total
  2. available
  3. leased
  4. failures

Redis 数据模型

对于池名 {pool_name},当前版本使用以下 Redis Key:

  1. credential_pool:{pool_name}:items Redis Hash,存储 key -> json
  2. credential_pool:{pool_name}:active Redis Set,存储所有激活凭证 key
  3. credential_pool:{pool_name}:available Redis Set,存储当前可独占获取的凭证 key
  4. credential_pool:{pool_name}:failures Redis Hash,存储 key -> failure_count
  5. credential_pool:{pool_name}:lease_owner Redis Hash,存储 key -> owner
  6. credential_pool:{pool_name}:lease_expiry Redis Sorted Set,存储 key -> expiry_ts

数据结构关系

flowchart TD
    A[items<br/>Hash: key -> json] --> B[active<br/>Set: 所有激活 key]
    B --> C[available<br/>Set: 当前可独占获取 key]
    A --> D[failures<br/>Hash: key -> failure_count]
    A --> E[lease_owner<br/>Hash: key -> owner]
    A --> F[lease_expiry<br/>ZSet: key -> expiry_ts]

说明

  1. items 是主数据存储。
  2. active 表示凭证仍在池内。
  3. available 表示该凭证当前未被独占持有。
  4. lease_ownerlease_expiry 一起构成租约系统。
  5. failures 用于业务层实现失败阈值控制。

推荐使用模式

适合使用 random_get()

  1. JWT 可被多个请求共享使用
  2. 无状态 Cookie
  3. 对单个凭证并发使用没有强限制的场景

适合使用 acquire_available()

  1. 单个凭证同一时间只能被一个 worker 使用
  2. 代理认证信息
  3. 有明显并发冲突风险的 Cookie / Token
  4. 需要“使用后归还”的场景

最佳实践

  1. key 设计成全局唯一且可读,例如 jwt:1cookie:user_001
  2. kind 用于标识凭证类型,例如 jwtcookienonce
  3. 独占获取后务必在 finally 中执行 release()
  4. 对长时间运行任务,建议定期执行 reclaim_expired_leases()
  5. 失败阈值删除策略建议由业务层自行控制,不要在 SDK 核心层写死

License

待补充。

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

credential_pool_sdk-0.1.0.tar.gz (11.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

credential_pool_sdk-0.1.0-py3-none-any.whl (8.6 kB view details)

Uploaded Python 3

File details

Details for the file credential_pool_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: credential_pool_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 11.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for credential_pool_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1a859fa48689858e513ee038d8cae846698151a2a2972103f4dc31ad9e68430b
MD5 7c47210306f52005042122d823942453
BLAKE2b-256 b17e731ccadf1ed8b2c89ae473f31720947e5b030abe6e85766d593614f12d24

See more details on using hashes here.

File details

Details for the file credential_pool_sdk-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for credential_pool_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 132fdf8f9765dcec1566d65a0225c34ab1c2de0858efff10ae589c1dc8a61362
MD5 4b11ed2f7b1418ec87539fa864c6d047
BLAKE2b-256 5e3d75b29fe5533e6fbc794f117d047c0c0e97605e3d677d18129ed07cdd5b65

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page