Coolhash 當前性能指標:讀寫吞吐量超過百萬,千萬級別查詢1秒完成,連續48小時打滿CPU強壓力運行穩定。redis官方公佈讀寫性能在10萬 tps,leveldb官方公佈寫性能在40萬tps,讀在6萬tps,redis和leveldb都是傾向k/v高速讀寫,但不具有高效檢索功能,沒有 join關聯設計。coolhash能夠拿去pk世界上任何的數據庫引擎產品。
下面以redis爲例進行了詳細測試和技術分析,leveldb 的性能可詳見其官方資料,在寫性能上優於redis,可是讀性能和多數據結構支持上不如redis,leveldb讀代價高是由於須要在內存以及各級數據 文件逐項查找並要優先考慮數據最新狀態,另外redis還提供server和集羣功能,leveldb不提供,redis是內存方式+內存快照持久化,而 leveldb是Memtable+硬盤持久化,leveldb持久化不受內存限制,也作到了接近緩存的性能,將來k/v數據庫的趨勢最好能直接看成緩存 使用,並能支持高效檢索功能。
按照redis的經常使用方式,咱們在一臺服務器上進行redis「單server」和「多server」的測試:java
從上面兩個圖,咱們能夠看到:git
redis是一個單進程單線程的實現,單server的讀寫TPS大概在8—12萬(跟redis官網公佈的數據一致),爲了充分利用可以資源,redis官方建議一臺機器部署多個redis server。redis
上面第二個圖的TPS超過了8-12萬的限制,這其實是在一臺服務器上部署了多個redis server,並將該服務器總的吞吐量算到一個redis server上獲得的。可是寫的時候是客戶端各自寫不一樣的redis server,多個redis server之間的數據是彼此獨立的,在不一樣的內存空間中,若是分開計算每一個redis server的寫入總量除以時間,TPS仍是在8-12萬左右。算法
咱們再到24核/256g/SATA硬盤的pc server上測試一下redis的benchmark,200個客戶端共寫入2000萬數據,發現性能變化不大,仍是在10萬左右的TPS,又測試了20個客戶端寫入2000萬數據,12萬TPS:數據庫
Redis很優秀,可是也有一些侷限:編程
redis不是一個並行數據庫,由單進程單線程實現,已經作到了單進程極限,性能很難再突破。若是要從新改寫redis,代價很大,並且 只有redis做者有能力作,其餘外圍的捐獻者動不了。redis官方採起一種曲線救國方式,不改變單進程模式,採起外圍作集羣,部署多個server來 提升CPU利用率,redis3.0的集羣方案使用一種hash slot算法(不是一致哈希),用多個redis server作數據分片存儲,按照crc16/16384取模方式,讓客戶端根據hash slot的配置尋址,擴容按照slot單位作數據遷移達到負載均衡。因爲在同臺服務器也存在多server實例集羣,會牽扯出不少server的 master-slave複製和數據遷移一致性等複雜性,也容易引發後端的IO爭用,特別是在AOF模式時。windows
redis是一種內存快照方式,也就意味着它的持久化大小受內存限制,不是真正的數據庫持久化存儲,內存是昂貴的,爲了擴大內存存儲,往 往須要更多的服務器搭建緩存集羣,redis做者曾想增長一種diskstore的全持久化+cache方式,採用SHA1算法來創建存儲結構,來改進內 存快照方式的種種不足,可是涉及到對redis底層持久化方式的重構,這個計劃從11年提出,截至到目前3.0版本,仍然尚未提供。後端
redis的存儲方式不是按照數據庫存儲索引結構設計,沒法作到高性能的按範圍、按key/value的模糊檢索,更多隻能在內存中進行全局數據的遍歷過濾,沒有高效的查詢功能,redis更適合作緩存讀寫,不適合看成數據庫存儲使用。api
國內的redis使用團隊更多也是在運維工具、監控管理、主備、故障恢復等等方面改進,不具有對上面redis的3點內核侷限的重構能力。
咱們接下來在同機環境(24核/256g/SATA硬盤)測試coolhash, 實際上coolhash也能夠像上面redis那樣在一臺服務器上部署多個server實例,可是咱們這裏啓動一個coolhash就夠了。 coolhash是一個並行數據庫引擎和數據庫server,能夠經過調整「coolhash數據工人數量、客戶端併發數量、每客戶端讀寫數量」三個指標 項達到一臺服務器的最佳吞吐量性能。
coolhash經過一組數據工人並行的完成任務,咱們先測試一個coolhash啓動多少個數據工 人最合適,下面在一臺服務器上運行coolhash並分別啓動1-96個工人,再用另一臺服務器模擬了200個客戶端併發,每一個客戶端寫入10萬數據, 累計2000萬數據,數據格式key=n(0
測試1:x個數據工人,200個客戶端併發,每一個客戶端寫入10萬數據緩存
數據工人 | 1個工人 | 8個工人 | 24個工人 | 32個工人 | 96個工人 |
耗時 | 400秒 | 40秒 | 20秒 | 23秒 | 25秒 |
cpu最高峯 | 10% | 20% | 75% | 85% | 90% |
TPS | 5萬/秒 | 50萬/秒 | 100萬/秒 | 87萬/秒 | 80萬/秒 |
分析:能夠清晰的看到並行數據庫的優點明顯,若是隻有一個數據工人,也就是單進程模式,它的TPS是很難 超出 10萬的,若是是8個數據工人並行做業,性能一會兒就能從400秒減小到40秒,提高10倍,但也不是數據工人越多性能越好,咱們看到24-32個工人是 個頂峯,若是再增長工人數雖然能提高cpu使用率,可是調度開銷大,後端硬盤io等跟不上,致使性能反而有所降低。
根據上面的結論,咱們配置coolhash啓動24個數據工人最合適,接下來再進一步調整「客戶端併發數」和「每一個客戶端寫入數量」,來達到一臺服務器的最佳性能。
測試2:24個數據工人,x個客戶端併發,每一個客戶端寫入10萬數據
客戶端數 | 1併發 | 10併發 | 20併發 | 50併發 | 100併發 | 200併發 |
寫入總量 | 10萬 | 100萬 | 200萬 | 500萬 | 1000萬 | 2000萬 |
耗時 | 1秒 | 3秒 | 5秒 | 10秒 | 18秒 | 20秒 |
TPS | 10萬/秒 | 33萬/秒 | 40萬/秒 | 50萬/秒 | 55萬/秒 | 100萬/秒 |
分析:若是每一個客戶端寫相同數量的數據,隨着併發數的提升,整體的吞吐量會高於單客戶端呈線性增加趨勢, 可是受 服務器cpu、內存、io等性能限制,不會一直增加,會傾向於一個平衡值。每臺服務器並非能承受無限大的併發數量,若是超出了承受限制,客戶端會長時間 等待,容易產生socket鏈接超時。合理的控制併發數量能提高服務器的吞吐性能,下面咱們增大每一個客戶端的寫入數量,減小總的併發數,並觀察效果。
測試3:24個數據工人,20個客戶端併發,每一個客戶端寫入x萬數據
每客戶端寫 | 10萬/每 | 50萬/每 | 100萬/每 | 200萬/每 | 300萬/每 |
寫入總量 | 200萬 | 1000萬 | 2000萬 | 4000萬 | 6000萬 |
耗時 | 4秒 | 6秒 | 10秒 | 15秒 | 22秒 |
寫TPS | 50萬/秒 | 167萬/秒 | 200萬/秒 | 267萬/秒 | 272萬/秒 |
分析:能夠看到一樣寫入2000萬數據,採用20併發*100萬比200併發*10萬的性能提高了一倍, 能達到 200萬以上TPS。這是由於客戶端創建鏈接後,一次提交100萬條數據的寫入請求,相比每條數據鏈接server,能很大節省網絡開銷和硬盤IO開銷。 由此咱們也能獲得,並非併發鏈接越多越好,而是控制必定數量的鏈接池性能會更好。
接下來咱們再以使用相同參數,測試一下讀的性能。
測試4:24個數據工人,20個客戶端併發,每一個客戶端讀出x萬數據
每客戶端讀 | 10萬/每 | 50萬/每 | 100萬/每 | 200萬/每 | 300萬/每 |
讀出總量 | 200萬 | 1000萬 | 2000萬 | 4000萬 | 6000萬 |
耗時 | 4秒 | 6秒 | 11秒 | 20秒 | 30秒 |
讀TPS | 50萬/秒 | 167萬/秒 | 182萬/秒 | 200萬/秒 | 200萬/秒 |
分析:coolhash是一個讀寫平衡的數據庫引擎,能夠看到讀和寫的性能相差不大,都能達到200萬的TPS。
coolhash 提供了高效的查詢檢索功能,能夠支持key和value的同時模糊查詢,下面按照600萬—3億不一樣的數據總量進行模糊查詢,數據格式爲key=n(0& lt;n<3億),value=n(0 CoolHashResult hr = chc.find("*", ValueFilter.contains(「8888888」))
測試5:24個數據工人,x個客戶端模糊查詢x萬數據
單個客戶端模糊查詢:
數據總量 | 600萬 | 2000萬 | 6000萬 | 1億 | 3億 |
耗時 | 0.9秒 | 1秒 | 1.7秒 | 2秒 | 6秒 |
多個客戶端高併發模糊查詢:
客戶端數 | 1併發 | 10併發 | 20併發 | 50併發 | 100併發 | 200併發 |
600萬 | 0.9秒 | 2秒 | 4秒 | 9秒 | 14秒 | 18秒 |
2000萬 | 1秒 | 4秒 | 9秒 | 21秒 | 37秒 | 45秒 |
分析:對於千萬級別的數據,客戶端一次任意模糊查詢的耗時都是在1秒完成,若是超過1億須要2秒,3億需 要6秒 (在沒有額外構建索引狀況下)。若是是100個客戶端併發模糊查詢,按照上面表格裏100併發查詢2000萬數據,平均耗時37秒,每次查詢耗時 37/100=0.37秒,每秒查詢次數100/37=2.7次,每秒查詢數據範圍大小100*2000萬/37秒=5400萬。這裏測試key是「*」 表明全部,若是key根據業務特色進行了分層設計,以「user.*.name」這樣形式模糊查詢,範圍會縮小,速度會更快。
測試6:壓力測試,200高併發下每客戶端讀取10萬數據連續48小時不間斷,服務端cpu、內存、帶寬資源高壓力運行穩定無異常。
下面概括一下coolhash和redis的基本區別:
redis | coolhash | |
實現語言 | c | java |
大小 | 2.3萬行代碼 | 小於1萬行(含fourinone) |
運行環境 | Linux | Linux/windows |
數據庫類型 | k/v緩存數據庫 | k/v持久化數據庫 |
實現模式 | 單進程模式,全部操做單線程完成 | 多進程模式,並行數據庫,全部操做並行完成 |
持久化模式 | 內存快照,aof日誌 | 硬盤持久化+cache |
存儲大小 | 受內存大小限制 | 無限制,取決硬盤大小 |
數據類型支持 | String,Hash,List,Set,Sorted set等,List是一個雙向鏈表實現,可用於實現消息隊列。 | 基本數據類型:「String、short、int、long、double、float、Date」,高級數據類型:大部分的java集合都能支持(List、Map、Set等),以及任意可序列化的自定義java類型,底層數據類型:二進制型 |
存儲結構 | redisDb內存結構,Key和key之間無聯繫,無上下層結構 | 按照數據庫索引存儲結構設計,CoolHash算法實現,支持key的樹型層次結構 |
查詢檢索 | 沒有針對範圍檢索設計 | Key索引+並行計算高效查詢,查詢性能在秒級 |
關聯設計 | 沒有針對join設計 | Key指針設計,並可連續指,支持創建1對一、1對n、n對n的複雜關聯關係 |
讀寫性能 | 單server吞吐量10萬tps(內存) | 單server可達到百萬以上tps(硬盤) |
事務處理 | 支持,但沒有事務隔離級別 | 支持ACID,實現TRANSACTION_SERIALIZABLE隔離級別 |
Server支持 | 支持 | 支持 |
命令行支持 | 支持 | 不支持 |
主備支持 | 直接支持,經過redis.conf配置主備 | 不直接支持,提供fttp分佈式備份api開發包支持 |
集羣支持 | 3.0版直接支持,經過hash slot算法 | 不直接支持,提供分佈式緩存集羣和fttp等開發包支持 |
總結:
首先不能簡單的以實現語言來衡量性能,認爲c實現的就必定比java高效,數據庫引擎的效率提高更多取決於底層算法改進和設計突破,c在底層和操做系統交互上有優點,可是取決於開發者,一個蹩腳的c工程師寫出的代碼只會低效和漏洞百出。
redis的優點在於快速的緩存讀寫、豐富的數據類型支持,以及完善的主備複製和集羣實現,劣勢在於單進程模式、內存限制、查詢檢索等方面。
coolhash是一個並行數據庫引擎,在不少地方採用了大膽創新的設計,並得到了很好的性能體驗,改進後的哈希算法能實現更快的 讀寫吞 吐量,key層次結構和key指針等設計能實現更高效的查詢檢索和join關聯。因爲只作數據庫引擎,暫不提供主備和集羣功能,可是fourinone提 供了大部分分佈式技術簡單實現的開發API,開發者能夠利用這些本身去實現。
隨着數據庫實現技術的發展,kv緩存和kv持久化存儲的性能愈來愈接近,邊界會愈來愈模糊,也會愈來愈涵蓋關係數據庫的功能。存儲硬件技術也在發展,將來在內存+ssd混合存儲上還會有更好的性能突破。
以上測試程序和運行包都來源於fourinone4.0版本,能夠到如下地址下載:
google code svn:http://fourinone.googlecode.com/svn/trunk/
國內oschina code:https://git.oschina.net/fourinone/fourinone/blob/master/fourinone-4.05.06.zip
CoolHash數據庫demo目錄內容:
RunServer.java:啓動服務端
RunClient.java:啓動客戶端
CoolHashTestRun.java:啓動多個併發客戶端
CoolHash做者聲明:歡迎各位朋友理性驗證和討論,不歡迎不理會各類噴子言論。
這 裏有不少人是redis和leveldb的使用者和封裝者,其中一部分人會看coolhash不爽,甚至失去理性變成噴子,對coolhash大加攻擊和 詆譭,但願coolhash只是玩具,但願coolhash沒有場景...可是噴子們要清楚本身的位置,redis和leveldb不是你的做品,你只是 站在洋人前面狐假虎威而已,核心層面的東西你甚至不具有發言權。長期以來國內工程師都是以學習和使用國外開源軟件爲生存技能,能理解這些人也只是混口飯 吃。
不少人軟件思想意識落後,「軟件傻瓜化」超出了他的理解範 圍,看到demo簡單,便誤認爲框架源碼也膚淺,看到demo裏沒有synchronized,便覺得框架沒有同步,有人甚至懷疑源碼是假的。demo簡 單是爲了保護用戶的自信心和駕馭感,用戶只須要看到一個美麗的軀殼,血肉模糊的東西留給框架戴着口罩拿着手術刀去作,這實際上對設計者提出了更大的難度, 因此源碼要實現那麼多功能,還要作到體驗傻瓜化,必定是很是精密的邏輯組成,源碼不可能像demo那樣通俗易懂。 一些人一來就對 fourinone源碼指手畫腳,評頭論足,大部分批評只停留在「編程規範、格式、變量名、包名、調了哪些工具類」這些層面,這些人須要多花時間提高本身 的技術積累、設計能力、算法能力,才能真正理解源碼的各類行爲,做者到過國內各類IT企業,很是清楚國內工程師的技術能力能到什麼程度,國內的開源軟件大 部分是基於國外開源軟件封裝後的二次開源,真正意義上的原創不多,大部分中國IT企業處在產業鏈末端,沒有核心技術,依靠外包勞動力,工程師的技術壽命很 短,平均只有3-5年,而後周圍環境會暗示他轉向管理或者業務,只有這樣才能獲得領導承認,技術積累過短暫,技術人員沒有悟性,也缺少興趣,過於依賴國 外,是不可能在覈心軟件層面有真正的原創。 一些人對coolhash很質疑,認爲不多人不多代碼實現不了高性能,實際上早在幾年 前,fourinone就在一片質疑聲中被要求壓測,結果出乎意料在計算性能上優於hadoop,如今coolhash只是重演了創新能力而已。建議各類 質疑者跟風者先放下政治偏見、利益衝突、情感排斥,耐心的動手去試試。對於技術上缺少分辨力的人,建議你認準三點,一看上手是否容易;二看功能是否強大; 三看性能是否高效,只要知足這三點就沒有人能夠忽悠得了你,而後你再結合源碼去反思是如何作到的。 曾國藩說過「竊喜洋人之智巧中國亦能爲之,彼不能傲我以其所不知矣!」 文 人不相輕,技術歸技術,本文對redis和leveldb的做者充滿尊敬和虛心學習,Salvatore Sanfilippo(antirez) 說過代碼像一首詩,Jeffrey Dean更是google map/reduce的做者,他們都表現出很高的職業素養和天賦,是這些人推進着世界軟件技術的發展,也成爲中國架構師心裏難以跨越的豐碑。是存在差距, 可是能夠站着學習,而不是跪着膜拜,一味跟從只會喪失判斷力和創新力,香港的年輕人曾經不相信大陸的taobao會比eBay強大,QQ會比MSN強大, 直到MSN垮了仍然不相信是真的,沒有信心,沒有努力,夢想只會變成作夢。 來自:http://my.oschina.net/fourinone/blog/289122