グローバル ID ジェネレーターは、分散システムでグローバルに一意の ID を生成するために使用されるツールです。通常、次の特性を満たします:
一意性: ID が固有であり、非固有であることを確認します。繰り返し可能
増分: 全体が徐々に増加していることを確認し、データベース作成インデックスに役立ちます
セキュリティ: ID の法則特に明らかではないため、ID 番号に基づいて他の ID を推測することを防ぎ、セキュリティを確保します
高パフォーマンス: ID の生成速度が十分に速いことを保証します
高可用性: いつでも使用できるようにする
ID のセキュリティを向上させるために、次を使用できます。 Redis の自動インクリメント値とその他の情報 ID は結合によって形成されます 具体的な合成方法は図に示すとおりです:
Sign bit : 1 ビット、常に 0、正の数を示します
タイムスタンプ: 31 ビット、秒単位、約 69 年間使用可能
シリアル数値: 32 ビット、同じ秒数の場合、ID シリアル番号の位置を増やして、1 秒あたり 2^32 の異なる ID の生成をサポートします
コード実装:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; @Component public class RedisIdWorker { /** * 开始时间戳 (2022-01-01 00:00:00) */ private static final long BEGIN_TIMESTAMP = 1640995200L; /** * 序列号的位数 */ private static final int COUNT_BITS = 32; @Autowired private StringRedisTemplate stringRedisTemplate; /** * 生成ID * * @param keyPrefix 业务系统的前缀 * @return ID */ public long nextId(String keyPrefix) { // 生成时间戳 long timestamp = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) - BEGIN_TIMESTAMP; // 生成序列号 String key = "icr:" + keyPrefix + ":" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy:MM:dd")); long count = stringRedisTemplate.opsForValue().increment(key); // 拼接并返回 return timestamp << COUNT_BITS | count; } /** * 获取时间戳 (2022-01-01 00:00:00) * @param args */ public static void main(String[] args) { LocalDateTime time = LocalDateTime.of(2022, 1, 1, 0, 0, 0); long second = time.toEpochSecond(ZoneOffset.UTC); System.out.println(second); } }
シリアル番号の生成:
Redis 自己インクリメントには上限があり、最大値は 2^64 です。この数字は大きいですが、やはり上限があり、時間が経てばこの数字を超える可能性もあります。したがって、たとえ同じ事業者であっても、同じキーを使用することはできません。したがって、icr: business name: 2022:05:14 のようにキーに日付を追加できます。この方法で生成されたキーは毎日新しいキーとなり、1 日の増分は 2^64 を超えないため、このようなキーの方が適切な選択です。
以上がRedis グローバル ID ジェネレーターを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。