CRC16 - redis集群槽计算

package com.sumavision.omc.microservice.bo.cache.manager.util;


/**
 * 测试: 解决场景:把1亿的用户 存储在一个队列里,过大。用sharding 摸拟redis 集群 sharding Redis
 * 集群使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现: 一个 Redis 集群包含 16384
 * 个哈希槽(hash slot), 数据库中的每个键都属于这 16384 个哈希槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键
 * key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。
 * <p>
 * Created by dailong on 2019/10/16.
 */
public class CRC16Util {
    
    public final static int maxInt = 1000;// 00000;//1亿
    public final static int USER_KEY_SLOT_COUNT = 20; // 定议分配存储用户的Slot位
    
    /******************************************************************************
     * Compilation: javac CRC16CCITT.java Execution: java CRC16CCITT s
     * Dependencies:
     *
     * Reads in a sequence of bytes and prints out its 16 bit Cylcic Redundancy
     * Check (CRC-CCIIT 0xFFFF).
     *
     * 1 + x + x^5 + x^12 + x^16 is irreducible polynomial.
     *
     * % java CRC16-CCITT 123456789 CRC16-CCITT = 29b1
     *
     ******************************************************************************/
    
    public static int crc16(final byte[] buffer) {
        
        int crc = 0xFFFF; // initial value 65535
        int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
        // byte[] testBytes = "123456789".getBytes("ASCII");
        for (byte b : buffer) {
            for (int i = 0; i < 8; i++) {
                boolean bit = ((b >> (7 - i) & 1) == 1);
                boolean c15 = ((crc >> 15 & 1) == 1);
                crc <<= 1;
                if (c15 ^ bit)
                    crc ^= polynomial;
            }
        }
        
        return crc &= 0xffff;
        
    }
    
    /**
     * @param buffer
     * @return
     */
    static int crc162(final byte[] buffer) {
        int crc = 0xFFFF;
        
        for (int j = 0; j < buffer.length; j++) {
            crc = ((crc >>> 8) | (crc << 8)) & 0xffff;
            crc ^= (buffer[j] & 0xff);// byte to int, trunc sign
            crc ^= ((crc & 0xff) >> 4);
            crc ^= (crc << 12) & 0xffff;
            crc ^= ((crc & 0xFF) << 5) & 0xffff;
        }
        crc &= 0xffff;
        return crc;
        
    }
    
    
    // ,如果存储有压力,可调大槽位
    public static void main(String[] args) {
        
        // int 不用crc16
        /*for (int i = 1; i < maxInt; i++) {
            // 根据玩家id 分布指定到Slot位
            int ranint = i % USER_KEY_SLOT_COUNT;
            String key = "key:" + ranint;
            System.out.println("key:" + key);
            // redisList.lpush(randomKey, String.valueOf(playerId));
        }*/
        
        /**
         * crc16 redis 集群也是用这种方式分配key
         */
        String a = "init_tager_temp";
        int solt = crc16(a.getBytes()) % 16384;
        
        String key = "key:" + solt;
        System.out.println("crc%solt=key:" + key);
        
        // redisList.lpush(randomKey, String.valueOf(playerId));
    }
    
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容