性能優化之 給redis插入分桶,制造物理索引


借助hbase的讀寫思路做數倉

hbase讀寫速度快(與HDFS對比)是基於兩方面:

1)用戶寫(入cache)和(cache)寫入硬盤是異步的

2)有-root-和-meta-表,能夠快速定位表的位置 => 成為物理化的標准索引

詳見:https://www.cnblogs.com/sabertobih/p/14001268.html

設計案例

需求描述:在mysql中存在2億數據,全是真葯。葯品id如果在庫中不存在,則為假葯。

要求給一個葯品id,能立刻判斷出是真葯假葯?

設計思路:

1)給mysql的id建立索引 => 會快一些,但僅僅是一些

2)在高速緩存中建立索引表,所有id插入key:value(set集合)時用加鹽哈希分桶,存儲set集合(防止mysql中真要id有重復)

=> 這樣我給一個id=12345,根據索引定位進某個桶,遍歷1000size的數據

=> 沒找到即為真葯 => 添加進mysql+redis

     找到即為假葯

優點:原本遍歷mysql2億數據量,現在只需要遍歷1000數據量

插入索引表

public static String tucketNo(int i){
        // 此方法如果String值特別大會出現負數
        // hadoop默認的hashpartitioner中為了解決這個問題,使用與運算:(key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
        return (i+"").hashCode()%100000+""; // 這里可以用abs取絕對值,否則生成200000個桶
}
Jedis jedis = new Jedis("192.168.56.111",6379);
Pipline pip = jedis.pipelined(); // 開啟Jedis的多線程操作
    for (int i = 0; i <200000000 ; i++) {
        pip.sadd(tucketNo(i),i+"");
            // 看進度條的
            if(i%100000==0){
                Thread.sleep(50);
                System.out.println(i);
            }
           
        }
pip.syns();
jedis.close();

性能測試

Jedis jedis = new Jedis("192.168.56.111",6379);
int no = 123344;
long time = System.currentTimeMillis();
 // 這個桶(value是set的key)是不是存在no這個數?
System.out.println(jedis.sismember(tucketNo(no),no+""));
// 判斷是否redis某個桶中存在某個數只花費了___milliseconds
System.out.println(System.currentTimeMillis()-time);

實現葯品需求偽代碼:找不到id則另開線程,異步寫入緩存+mysql

if 找不到這個id
=>
new Thread(new Runnable(){
    @overrideid
    public void run(){
        sout("id插入數據庫mysql")
        jedis.sadd(tucketNo(no),no+""); // id插入索引
        sout()
    }
}).start()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM