国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Sharding-JDBC 自定義一致性哈希算法 + 虛擬節(jié)點(diǎn) 實(shí)現(xiàn)數(shù)據(jù)庫分片策略

這篇具有很好參考價(jià)值的文章主要介紹了Sharding-JDBC 自定義一致性哈希算法 + 虛擬節(jié)點(diǎn) 實(shí)現(xiàn)數(shù)據(jù)庫分片策略。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1. Sharding-JDBC 分片策略

分片操作是分片鍵 + 分片算法,也就是分片策略。目前Sharding-JDBC 支持多種分片策略:

  • 標(biāo)準(zhǔn)分片策略
    對應(yīng)StandardShardingStrategy。提供對SQL語句中的=, IN和BETWEEN AND的分片操作支持。
  • 復(fù)合分片策略
    對應(yīng)ComplexShardingStrategy。復(fù)合分片策略。提供對SQL語句中的=, IN和BETWEEN AND的分片操作支持。
  • 行表達(dá)式分片策略
    對應(yīng)InlineShardingStrategy。使用Groovy的表達(dá)式,提供對SQL語句中的=和IN的分片操作支持,只支持單分片鍵。
  • Hint分片策略
    對應(yīng)HintShardingStrategy。通過Hint而非SQL解析的方式分片的策略。

具體的請參考官方文檔:sharding分片策略

2. Sharding-JDBC 分片算法

分片算法需要應(yīng)用方開發(fā)者自行實(shí)現(xiàn),可實(shí)現(xiàn)的靈活度非常高。

目前 Sharding-JDBC提供4種分片算法。由于分片算法和業(yè)務(wù)實(shí)現(xiàn)緊密相關(guān),因此并未提供內(nèi)置分片算法,而是通過分片策略將各種場景提煉出來,提供更高層級的抽象,并提供接口讓應(yīng)用開發(fā)者自行實(shí)現(xiàn)分片算法。

  • 精確分片算法
    對應(yīng)PreciseShardingAlgorithm,用于處理使用單一鍵作為分片鍵的=與IN進(jìn)行分片的場景。需要配合StandardShardingStrategy使用。

  • 范圍分片算法
    對應(yīng)RangeShardingAlgorithm,用于處理使用單一鍵作為分片鍵的BETWEEN AND進(jìn)行分片的場景。需要配合StandardShardingStrategy使用。

  • 復(fù)合分片算法
    對應(yīng)ComplexKeysShardingAlgorithm,用于處理使用多鍵作為分片鍵進(jìn)行分片的場景,包含多個(gè)分片鍵的邏輯較復(fù)雜,需要應(yīng)用開發(fā)者自行處理其中的復(fù)雜度。需要配合ComplexShardingStrategy使用。

  • Hint分片算法
    對應(yīng)HintShardingAlgorithm,用于處理使用Hint行分片的場景。需要配合HintShardingStrategy使用。

3. 自定義一致性哈希算法實(shí)踐

什么是一致性哈希算法 請看這篇博客:

  1. 首先實(shí)現(xiàn)ShardingJDBC提供的接口:
    • PreciseShardingAlgorithm:精確分片算法,如果使用 == 來判定分片的情況,需要實(shí)現(xiàn)這個(gè)接口。
    • RangeShardingAlgorithm:范圍分片,如果有使用范圍查找的話,需要使用這個(gè)進(jìn)行分片策略。

/**
 * 自定義哈希算法 + 虛擬節(jié)點(diǎn)實(shí)現(xiàn)數(shù)據(jù)分片
 * 使用FNV1_32_HASH算法計(jì)算key的Hash值
 * 也可以使用 MurmurHash3 或者別的加密方式
 * @author manji
 * @Date 2023/5/4
 */
public class ConsistenceHashAlgorithm implements RangeShardingAlgorithm<Long>, PreciseShardingAlgorithm<Long> {
    /**
     * 范圍查找時(shí)需要用到改分片算法,這里暫不完善了
     * @param collection
     * @param rangeShardingValue
     * @return
     */
    @Override
    public Collection<String> doSharding(Collection collection, RangeShardingValue rangeShardingValue) {
        System.out.println(collection);
        System.out.println(rangeShardingValue);
        return collection;
    }

    /**
     * @param collection collection 配置文件中解析到的所有分片節(jié)點(diǎn)
     * @param preciseShardingValue 解析到的sql值
     * @return 
     */
    @Override
    public String doSharding(Collection collection, PreciseShardingValue preciseShardingValue) {
        System.out.println(collection);
        InitTableNodesToHashLoop initTableNodesToHashLoop = SpringUtils.getBean(InitTableNodesToHashLoop.class);
        if (CollectionUtils.isEmpty(collection)) {
            return preciseShardingValue.getLogicTableName();
        }

        //這里主要為了兼容當(dāng)聯(lián)表查詢時(shí),如果兩個(gè)表非關(guān)聯(lián)表則
        //當(dāng)對副表分表時(shí)shardingValue這里傳遞進(jìn)來的依然是主表的名稱,
        //但availableTargetNames中確是副表名稱,所有這里要從availableTargetNames中匹配真實(shí)表
        ArrayList<String> availableTargetNameList = new ArrayList<>(collection);
        String logicTableName = availableTargetNameList.get(0).replaceAll("[^(a-zA-Z_)]", "");
        SortedMap<Long, String> tableHashNode =
                initTableNodesToHashLoop .getTableVirtualNodes().get(logicTableName);

        ConsistenceHashUtil consistentHashAlgorithm = new ConsistenceHashUtil(tableHashNode,
                collection);

        return consistentHashAlgorithm.getTableNode(String.valueOf(preciseShardingValue.getValue()));
    }
}
  1. 初始化hash環(huán)
    注意@Lazy 不添加的話會報(bào)錯(cuò)ShardingDataSource 找不到,因?yàn)樵诩虞d該類時(shí),ShardingDataSource 還未放入容器中,所以獲取不到,所以使用@Lazy 注解延后該類的加載。
/**
 * 初始化hash環(huán)
 * @author manji
 * @Date 2023/5/4
 */
@Slf4j
@Component
@Lazy
public class InitTableNodesToHashLoop {

    @Resource
    private ShardingDataSource shardingDataSource;

    @Getter
    private HashMap<String, SortedMap<Long, String>> tableVirtualNodes = new HashMap<>();

    @PostConstruct
    public void init() {
        try {
            ShardingRule rule = shardingDataSource.getShardingContext().getShardingRule();
            Collection<TableRule> tableRules = rule.getTableRules();
            ConsistenceHashUtil consistenceHashUtil = new ConsistenceHashUtil();
            for (TableRule tableRule : tableRules) {
                String logicTable = tableRule.getLogicTable();

                tableVirtualNodes.put(logicTable,
                        consistenceHashUtil.initNodesToHashLoop(
                                tableRule.getActualDataNodes()
                                        .stream()
                                        .map(DataNode::getTableName)
                                        .collect(Collectors.toList()))
                );
            }
        } catch (Exception e) {
            log.error("分表節(jié)點(diǎn)初始化失敗 {}", e);
        }
    }
}

  1. 一致性hash算法的核心代碼

/**
 * 一致性哈希算法工具類
 * @author manji
 * @Date 2023/5/4
 */
public class ConsistenceHashUtil {

    //存儲所有節(jié)點(diǎn),按照hash值排序的
    @Getter
    private SortedMap<Long, String> virtualNodes = new TreeMap<>();

    // 設(shè)置虛擬節(jié)點(diǎn)的個(gè)數(shù)
    private static final int VIRTUAL_NODES = 3;


    public ConsistenceHashUtil() {
    }


    public ConsistenceHashUtil(SortedMap<Long, String> virtualTableNodes, Collection<String> tableNodes) {
        if (Objects.isNull(virtualTableNodes)) {
            virtualTableNodes = initNodesToHashLoop(tableNodes);
        }

        this.virtualNodes = virtualTableNodes;
    }

    public SortedMap<Long, String> initNodesToHashLoop(Collection<String> tableNodes) {
        SortedMap<Long, String> virtualTableNodes = new TreeMap<>();
        for (String node : tableNodes) {
            for (int i = 0; i < VIRTUAL_NODES; i++) {
                String s = String.valueOf(i);
                String virtualNodeName = node + "-manji" + s;
                long hash = getHash(virtualNodeName);

                virtualTableNodes.put(hash, virtualNodeName);
            }
        }

        return virtualTableNodes;
    }

    /**
     * 通過計(jì)算key的hash
     * 計(jì)算映射的表節(jié)點(diǎn)
     *
     * @param key
     * @return
     */
    public String getTableNode(String key) {
        String virtualNode = getVirtualTableNode(key);
        //虛擬節(jié)點(diǎn)名稱截取后獲取真實(shí)節(jié)點(diǎn)
        if (!StringUtils.isEmpty(virtualNode)) {
            return virtualNode.substring(0, virtualNode.indexOf("-"));
        }
        return null;
    }

    /**
     * 獲取虛擬節(jié)點(diǎn)
     * @param key
     * @return
     */
    public String getVirtualTableNode(String key) {
        long hash = getHash(key);
        // 得到大于該Hash值的所有Map
        SortedMap<Long, String> subMap = virtualNodes.tailMap(hash);
        String virtualNode;
        if (subMap.isEmpty()) {
            //如果沒有比該key的hash值大的,則從第一個(gè)node開始
            Long i = virtualNodes.firstKey();
            //返回對應(yīng)的服務(wù)器
            virtualNode = virtualNodes.get(i);
        } else {
            //第一個(gè)Key就是順時(shí)針過去離node最近的那個(gè)結(jié)點(diǎn)
            Long i = subMap.firstKey();
            //返回對應(yīng)的服務(wù)器
            virtualNode = subMap.get(i);
        }

        return virtualNode;
    }

    /**
     * 使用FNV1_32_HASH算法計(jì)算key的Hash值
     * 也可以使用 MurmurHash3 或者別的加密方式
     * @param key
     * @return
     */
    public long getHash(String key) {
//        return MurmurHash3.murmurhash3_x86_32(key);
        final int p = 16777619;
        int hash = (int) 2166136261L;
        for (int i = 0; i < key.length(); i++)
            hash = (hash ^ key.charAt(i)) * p;
        hash += hash << 13;
        hash ^= hash >> 7;
        hash += hash << 3;
        hash ^= hash >> 17;
        hash += hash << 5;

        // 如果算出來的值為負(fù)數(shù)則取其絕對值
        if (hash < 0)
            hash = Math.abs(hash);
        return hash;
    }

}

  1. 配置Sharding-JDBC的分片策略

spring.main.allow-bean-definition-overriding = true

mybatis.configuration.map-underscore-to-camel-case = true

#數(shù)據(jù)源
spring.shardingsphere.datasource.names = m1

#數(shù)據(jù)源1
spring.shardingsphere.datasource.m1.type = com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name = com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.url = jdbc:mysql://localhost:3306/shardingdemo?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
spring.shardingsphere.datasource.m1.username = root
spring.shardingsphere.datasource.m1.password = 12345678


spring.shardingsphere.sharding.default-data-source-name=m1

# 指定user表的數(shù)據(jù)分布情況
spring.shardingsphere.sharding.tables.user.actual-data-nodes = m1.user_$->{0..2}
# 指定user表的分片策略,分片策略包括分片鍵和分片算法
spring.shardingsphere.sharding.tables.user.table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.user.table-strategy.standard.precise-algorithm-class-name=com.manji.shardingdemo.consistencehasg.ConsistenceHashAlgorithm


# 打開sql輸出日志
spring.shardingsphere.props.sql.show = true

代碼demo地址:sharding-一致性哈希算法文章來源地址http://www.zghlxwxcb.cn/news/detail-433934.html

到了這里,關(guān)于Sharding-JDBC 自定義一致性哈希算法 + 虛擬節(jié)點(diǎn) 實(shí)現(xiàn)數(shù)據(jù)庫分片策略的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 區(qū)塊鏈:哈希算法與一致性哈希算法

    本篇主要介紹區(qū)塊鏈中常用到的哈希算法。 1 哈希算法 1.1 定義及特性 ??哈希算法是指通過哈希函數(shù)(Hash Function)對任意長度的輸入數(shù)據(jù)(比如文件、消息、數(shù)字等)進(jìn)行轉(zhuǎn)換,生成一個(gè)固定長度的哈希值(Hash Value)的過程。 ??在區(qū)塊鏈中,哈希算法常用于區(qū)塊驗(yàn)證及安全性保

    2024年02月17日
    瀏覽(22)
  • 一致性哈希(哈希環(huán))解決數(shù)據(jù)分布問題

    哈希算法是程序開發(fā)過程中最廣泛接觸到的的算法之一,典型的應(yīng)用有安全加密、數(shù)據(jù)校驗(yàn)、唯一標(biāo)識、散列函數(shù)、負(fù)載均衡、數(shù)據(jù)分片、分布式存儲。前些天遇到用一致性哈希(哈希環(huán))的場景,不過我細(xì)想一下,對這個(gè)知識點(diǎn)好像了解過,但是又沒太深印象,說不出具體

    2024年02月04日
    瀏覽(27)
  • 【負(fù)載均衡——一致性哈希算法】

    【負(fù)載均衡——一致性哈希算法】

    一致性哈希算法就很好地解決了分布式系統(tǒng)在擴(kuò)容或者縮容時(shí),發(fā)生過多的數(shù)據(jù)遷移的問題。 一致哈希算法也用了取模運(yùn)算,但與哈希算法不同的是,哈希算法是對節(jié)點(diǎn)的數(shù)量進(jìn)行取模運(yùn)算,而一致 哈希算法 是對 2^32 進(jìn)行取模運(yùn)算,是一個(gè)固定的值。 一致性哈希要進(jìn)行兩步

    2024年04月10日
    瀏覽(25)
  • 07. 算法之一致性哈希算法介紹

    07. 算法之一致性哈希算法介紹

    哈希算法在程序開發(fā)中的很多地方都能看到他的身影,但是哈希有他的局限性,比如如果兩個(gè)key哈希到同一個(gè)位置的時(shí)候,此時(shí)就不好處理。本節(jié)我們介紹一下常規(guī)處理方式。 哈希算法將任意長度的二進(jìn)制值映射為較短的固定長度的二進(jìn)制值,這個(gè)小的二進(jìn)制值稱為哈希值。

    2024年02月06日
    瀏覽(24)
  • Python小知識 - 一致性哈希算法

    Python小知識 - 一致性哈希算法

    一致性哈希算法 一致性哈希算法(Consistent Hashing Algorithm)是用于解決分布式系統(tǒng)中節(jié)點(diǎn)增減比較頻繁的問題。它的思想是,將數(shù)據(jù)映射到0~2^64-1的哈??臻g中,并通過哈希函數(shù)對數(shù)據(jù)進(jìn)行映射,計(jì)算出數(shù)據(jù)所在的節(jié)點(diǎn)。當(dāng)節(jié)點(diǎn)增加或減少時(shí),只需要重新計(jì)算數(shù)據(jù)所在的節(jié)點(diǎn)即

    2024年02月09日
    瀏覽(17)
  • Dubbo負(fù)載均衡策略之 一致性哈希

    Dubbo負(fù)載均衡策略之 一致性哈希

    本文主要講解了一致性哈希算法的原理以及其存在的數(shù)據(jù)傾斜的問題,然后引出解決數(shù)據(jù)傾斜問題的方法,最后分析一致性哈希算法在Dubbo中的使用。通過這篇文章,可以了解到一致性哈希算法的原理以及這種算法存在的問題和解決方案。 在這里引用dubbo官網(wǎng)的一段話——

    2024年02月08日
    瀏覽(23)
  • 一致性哈希算法優(yōu)勢在哪?如何實(shí)現(xiàn)?

    1.1 簡介Hash 哈希算法即散列算法,是一種從任意文件中創(chuàng)造小的數(shù)字「指紋」的方法。與指紋一樣,散列算法就是一種以較短的信息來保證文件唯一性的標(biāo)志,這種標(biāo)志與文件的每一個(gè)字節(jié)都相關(guān),而且難以找到逆向規(guī)律。因此,當(dāng)原有文件發(fā)生改變時(shí),其標(biāo)志值也會發(fā)生改

    2024年02月03日
    瀏覽(34)
  • Redis擴(kuò)容機(jī)制與一致性哈希算法解析

    在分布式系統(tǒng)設(shè)計(jì)中,Redis是一個(gè)備受歡迎的內(nèi)存數(shù)據(jù)庫,而一致性哈希算法則是分布式系統(tǒng)中常用的數(shù)據(jù)分片和負(fù)載均衡技術(shù)。本文將深入探討Redis的擴(kuò)容機(jī)制以及一致性哈希算法的原理,同時(shí)提供示例代碼以幫助讀者更好地理解這兩個(gè)重要概念。 Redis是一種高性能的內(nèi)存數(shù)

    2024年02月11日
    瀏覽(42)
  • 得物面試:Redis用哈希槽,而不是一致性哈希,為什么?

    得物面試:Redis用哈希槽,而不是一致性哈希,為什么?

    在40歲老架構(gòu)師 尼恩的 讀者交流群 (50+)中,最近有小伙伴拿到了一線互聯(lián)網(wǎng)企業(yè)如得物、阿里、滴滴、極兔、有贊、希音、百度、網(wǎng)易、美團(tuán)的面試資格,遇到很多很重要的面試題: Redis為何用哈希槽而不用一致性哈希? 最近有小伙伴在面試網(wǎng)易,又遇到了相關(guān)的面試題。

    2024年02月21日
    瀏覽(24)
  • Dubbo負(fù)載均衡策略之 一致性哈希 | 京東云技術(shù)團(tuán)隊(duì)

    Dubbo負(fù)載均衡策略之 一致性哈希 | 京東云技術(shù)團(tuán)隊(duì)

    本文主要講解了一致性哈希算法的原理以及其存在的數(shù)據(jù)傾斜的問題,然后引出解決數(shù)據(jù)傾斜問題的方法,最后分析一致性哈希算法在Dubbo中的使用。通過這篇文章,可以了解到一致性哈希算法的原理以及這種算法存在的問題和解決方案。 在這里引用dubbo官網(wǎng)的一段話——

    2024年02月08日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包