ホームページ  >  記事  >  データベース  >  Redis グローバル ID ジェネレーターを実装する方法

Redis グローバル ID ジェネレーターを実装する方法

PHPz
PHPz転載
2023-05-27 12:02:491417ブラウズ

グローバル ID ジェネレーターは、分散システムでグローバルに一意の ID を生成するために使用されるツールです。通常、次の特性を満たします:

  • 一意性: ID が固有であり、非固有であることを確認します。繰り返し可能

  • 増分: 全体が徐々に増加していることを確認し、データベース作成インデックスに役立ちます

  • セキュリティ: ID の法則特に明らかではないため、ID 番号に基づいて他の ID を推測することを防ぎ、セキュリティを確保します

  • 高パフォーマンス: ID の生成速度が十分に速いことを保証します

  • 高可用性: いつでも使用できるようにする

実装原則:

ID のセキュリティを向上させるために、次を使用できます。 Redis の自動インクリメント値とその他の情報 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 サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。