firebody 寫道:
java 代碼
?
?? 1. 以前用hibernate主要是做一些表的映射、關聯,更深層的應用就沒有了,所以也沒什么經驗,拿個具體的情況來分析一下吧。? ?
?? 2.? ?
?? 3. 目前主要數據庫是mysql,由于數據庫存儲限制:? ?
?? 4. 1、通常會把用戶名和密碼放一個庫(負載相對較少,但也要依賴cache)。? ?
?? 5. 2、用戶基本資料拆開多臺DB按用戶名或ID hash,用戶擴展信息也拆開多臺。? ?
?? 6. 3、用戶積分因為太敏感,甚至使用了oracle來保證效率和穩定性(事實證明它比mysql慢。。它的C++綁定也更不穩定)。? ?
?? 7. 4、用戶發帖是保存在文件的,數據庫只保存文件鏈接發帖人等簡單信息。? ?
?? 8. 5、用戶之間的消息是放數據庫的,當然也是按用戶名hash到多臺,這時候要查詢我給別人的消息和別人給我的消息,就得從2個表里面查,因為你給別人的消息是按別人的用戶名hash到某一臺上,別人給你的是按你的用戶名hash的,所以增加一條消息就得往2個庫各寫一條。? ?
?? 9.? ?
? 10. 以上列舉了一部分應用,當然由于庫拆得比較散,基本上每個庫都會有冗余字段。? ?
? 11.? ?
? 12. 上面這種情況下,能不能分析一下hibernate和ActiveRecord用得比較舒服的部分?? ?
? 13.? ?
? 14. 我在用rails的時候,ActiveRecord對于多數據庫支持并不好,即使是有這樣的方案也是非方的技巧。分表情況下表之間的關聯基本上沒法做,如果沒有關聯,ActiveRecord的意義只是幫我們生成SQL?? ?
? 15.? ?
? 16. 多級目錄不是最大的問題,也不是阻礙性能的問題,俺只想找個最后的理由把RoR不適用這個項目說得更充分些。。。 ?
?
謝謝你能夠提供更多的信息來參與討論, 針對你提到的2),這樣的情況下,按照我的理解,現有的java的orm框架無法針對不同庫的表作映射。 activeRecord應該也沒有考慮到這種情況。
不知道你們作出的分庫的依據是什么,我覺得更合理的分庫依據應該根據負載壓力和模塊獨立性來分離,比如你提到的消息發送應該是統一的模塊,按照用戶名hash到不同的庫的話,對于業務層開發帶來一定的復雜度。
分表的話,java的orm有些策略可以繞著解決,比如用繼承策略來解決。但是也是比較別扭。 不過,我更想了解的是你們作出的分表的依據是什么?
這樣的情況下,模型的關聯映射在現有的orm框架下確實太牽強了,即使用了,收到的效果也是很小的,模型也會隨之退化到單實體+基本類型外鍵的維護上來,如果讓我選擇的話,基本上也是選擇spring的jdbcTemplate了。
如果覺得java orm是促進開發效率的一個基本前提的話,那么在系統架構選擇上,特別是數據庫架構設計上,可能還要更慎重一些,因為不同于數據庫底層開發,orm對于數據庫的要求會有一些苛刻。為了最大化獲得模型映射的效果,有一些建議不知道是否合理:
*? 在考慮訪問壓力的情況下,盡量按照耦合緊密的原則分庫,使得某一個庫的表關聯能夠作充分的模型映射,而對于少數的外庫關聯仍然需要做手工的維護,不過已經簡化到最小。
*? 因為數據量大而分表的話,可以采用多態映射關聯來做和多表的關聯。
基本上分庫主要原因都是和容量或性能有關,上億用戶,每個用戶只保存一個用戶名和密碼,也有好幾G的數據。
為了登錄部分效率考慮,用戶名和密碼拆到一個庫中,因為這部分讀取并不是特別頻繁,所以目前用主備方式,備的目的是主掛掉至少不會讓用戶無法登錄,頂多無法注冊而已。
用戶的基本資料字段是固定的,但容量有些大,訪問也比較頻繁。之前用戶沒有中間層,所以拆庫來提高效率。現在有中間層,拆庫的意義也變了,領導不希望任何一臺機器故障影響到所有用戶,影響部分用戶還是勉強可接受的。實際上隨著用戶的不斷增加,即便是使用中間層也會有壓力,畢竟中間層只是幫數據庫擋了讀取的壓力,而讀寫比例通常情況下是10:1左右。
用戶擴展信息,這個是一對多的,一個用戶可自定義不同的字段,通常是用戶有修改時更新一下,讀取壓力并不大,同樣是因為中間把把讀取壓力都擋掉了,但容量非常大。
當然也考慮過如果有中間層,是不是數據庫不用拆得這么細,目前也做過一些合并工作,不過意義并不大,因為所有數據庫容量加起來以T計,不管是備份還是擴容甚至修復硬件故障都會影響用戶很長時間,現在拆得這么細,通常一個點的故障只會影響一部分用戶的一部分功能。目前硬件故障還是會經常有的,比如某國外品牌的服務器故障率非常高。擴容也是經常會有的,文件每天上傳量就超過2T,每月都增加存儲。數據庫差不多每3月-6月都要重新拆分一次,因為容量。
分庫分表最佳實踐大總結
一、隨著企業業務的增長,訪問量和用戶等數據的增加,傳統的關系數據庫已經不能滿足需求
分表分庫就成了節省成本、和良好擴展性的必然選擇
網上也有很多開源的分表分庫的軟件,也公司自己開發實現
而終其原理和步驟都無外乎三步:
? 即首先sql解析路由,再根據路由確定分片,然后結果集合并
? 所遇到的分表分庫的難點大都是對分布式事務的支持,分片后的分頁
和排序等
二、實現方式大都在兩個層面:
即在應用層 代表有hibernate shards,ibatis shards,guzz 等
和 在jdbc之下 對應用層完全透明的 如amoeba
三、那么企業在分表分庫的實踐中該如何選擇呢?
假如您是一開始就想全新的分表分庫 公司沒打算做自己的分表分庫框架,那么推薦用guzz,
這個類似于hibernate 和 ibatis的框架,很多網站都在用,缺點是技術團隊需要重新學習一套框架
跟舊的系統很難兼容;
假如您的系統很亂,分表分庫規則很簡單,并且數據庫是mysql
推薦用amoeba ,雖然有oracle版本,但目前不是很成熟;
假如您的技術團隊一直用hibernate ,或企業現在的很多項目現在都用hibernate做的
那么推薦用hibernate shards,這個類似hibernate,學習成本低,能跟
hibernate兼容
目前國內有在hibernate? shards上封裝的成功案例,
缺點是list查詢時遍歷所有數據片,而不是根據sql規則確定的數據片。
這個bug及在hibernate shards上如何擴展問題我已解決,附件是解決的架構圖,
需要源代碼的或詳細可以聯系我;
ibatis shards跟hibernate shards類似,也可借鑒本人所設計的架構
思想 歡迎有志之士詳聊
附:
一、hibernate shards
優點:
1、實現跟其他成熟框架的集成如spring
等
2、能利用公司現有的hibernate的技術優勢
3、目前國內有成功案例在hibernate? shards上封裝
的商業軟件
4、能夠快速開發
缺點:
1、暫不支持垂直分區
2、list查詢遍歷所有表分片
java 代碼
?
?? 1. 以前用hibernate主要是做一些表的映射、關聯,更深層的應用就沒有了,所以也沒什么經驗,拿個具體的情況來分析一下吧。? ?
?? 2.? ?
?? 3. 目前主要數據庫是mysql,由于數據庫存儲限制:? ?
?? 4. 1、通常會把用戶名和密碼放一個庫(負載相對較少,但也要依賴cache)。? ?
?? 5. 2、用戶基本資料拆開多臺DB按用戶名或ID hash,用戶擴展信息也拆開多臺。? ?
?? 6. 3、用戶積分因為太敏感,甚至使用了oracle來保證效率和穩定性(事實證明它比mysql慢。。它的C++綁定也更不穩定)。? ?
?? 7. 4、用戶發帖是保存在文件的,數據庫只保存文件鏈接發帖人等簡單信息。? ?
?? 8. 5、用戶之間的消息是放數據庫的,當然也是按用戶名hash到多臺,這時候要查詢我給別人的消息和別人給我的消息,就得從2個表里面查,因為你給別人的消息是按別人的用戶名hash到某一臺上,別人給你的是按你的用戶名hash的,所以增加一條消息就得往2個庫各寫一條。? ?
?? 9.? ?
? 10. 以上列舉了一部分應用,當然由于庫拆得比較散,基本上每個庫都會有冗余字段。? ?
? 11.? ?
? 12. 上面這種情況下,能不能分析一下hibernate和ActiveRecord用得比較舒服的部分?? ?
? 13.? ?
? 14. 我在用rails的時候,ActiveRecord對于多數據庫支持并不好,即使是有這樣的方案也是非方的技巧。分表情況下表之間的關聯基本上沒法做,如果沒有關聯,ActiveRecord的意義只是幫我們生成SQL?? ?
? 15.? ?
? 16. 多級目錄不是最大的問題,也不是阻礙性能的問題,俺只想找個最后的理由把RoR不適用這個項目說得更充分些。。。 ?
?
謝謝你能夠提供更多的信息來參與討論, 針對你提到的2),這樣的情況下,按照我的理解,現有的java的orm框架無法針對不同庫的表作映射。 activeRecord應該也沒有考慮到這種情況。
不知道你們作出的分庫的依據是什么,我覺得更合理的分庫依據應該根據負載壓力和模塊獨立性來分離,比如你提到的消息發送應該是統一的模塊,按照用戶名hash到不同的庫的話,對于業務層開發帶來一定的復雜度。
分表的話,java的orm有些策略可以繞著解決,比如用繼承策略來解決。但是也是比較別扭。 不過,我更想了解的是你們作出的分表的依據是什么?
這樣的情況下,模型的關聯映射在現有的orm框架下確實太牽強了,即使用了,收到的效果也是很小的,模型也會隨之退化到單實體+基本類型外鍵的維護上來,如果讓我選擇的話,基本上也是選擇spring的jdbcTemplate了。
如果覺得java orm是促進開發效率的一個基本前提的話,那么在系統架構選擇上,特別是數據庫架構設計上,可能還要更慎重一些,因為不同于數據庫底層開發,orm對于數據庫的要求會有一些苛刻。為了最大化獲得模型映射的效果,有一些建議不知道是否合理:
*? 在考慮訪問壓力的情況下,盡量按照耦合緊密的原則分庫,使得某一個庫的表關聯能夠作充分的模型映射,而對于少數的外庫關聯仍然需要做手工的維護,不過已經簡化到最小。
*? 因為數據量大而分表的話,可以采用多態映射關聯來做和多表的關聯。
基本上分庫主要原因都是和容量或性能有關,上億用戶,每個用戶只保存一個用戶名和密碼,也有好幾G的數據。
為了登錄部分效率考慮,用戶名和密碼拆到一個庫中,因為這部分讀取并不是特別頻繁,所以目前用主備方式,備的目的是主掛掉至少不會讓用戶無法登錄,頂多無法注冊而已。
用戶的基本資料字段是固定的,但容量有些大,訪問也比較頻繁。之前用戶沒有中間層,所以拆庫來提高效率。現在有中間層,拆庫的意義也變了,領導不希望任何一臺機器故障影響到所有用戶,影響部分用戶還是勉強可接受的。實際上隨著用戶的不斷增加,即便是使用中間層也會有壓力,畢竟中間層只是幫數據庫擋了讀取的壓力,而讀寫比例通常情況下是10:1左右。
用戶擴展信息,這個是一對多的,一個用戶可自定義不同的字段,通常是用戶有修改時更新一下,讀取壓力并不大,同樣是因為中間把把讀取壓力都擋掉了,但容量非常大。
當然也考慮過如果有中間層,是不是數據庫不用拆得這么細,目前也做過一些合并工作,不過意義并不大,因為所有數據庫容量加起來以T計,不管是備份還是擴容甚至修復硬件故障都會影響用戶很長時間,現在拆得這么細,通常一個點的故障只會影響一部分用戶的一部分功能。目前硬件故障還是會經常有的,比如某國外品牌的服務器故障率非常高。擴容也是經常會有的,文件每天上傳量就超過2T,每月都增加存儲。數據庫差不多每3月-6月都要重新拆分一次,因為容量。
分庫分表最佳實踐大總結
一、隨著企業業務的增長,訪問量和用戶等數據的增加,傳統的關系數據庫已經不能滿足需求
分表分庫就成了節省成本、和良好擴展性的必然選擇
網上也有很多開源的分表分庫的軟件,也公司自己開發實現
而終其原理和步驟都無外乎三步:
? 即首先sql解析路由,再根據路由確定分片,然后結果集合并
? 所遇到的分表分庫的難點大都是對分布式事務的支持,分片后的分頁
和排序等
二、實現方式大都在兩個層面:
即在應用層 代表有hibernate shards,ibatis shards,guzz 等
和 在jdbc之下 對應用層完全透明的 如amoeba
三、那么企業在分表分庫的實踐中該如何選擇呢?
假如您是一開始就想全新的分表分庫 公司沒打算做自己的分表分庫框架,那么推薦用guzz,
這個類似于hibernate 和 ibatis的框架,很多網站都在用,缺點是技術團隊需要重新學習一套框架
跟舊的系統很難兼容;
假如您的系統很亂,分表分庫規則很簡單,并且數據庫是mysql
推薦用amoeba ,雖然有oracle版本,但目前不是很成熟;
假如您的技術團隊一直用hibernate ,或企業現在的很多項目現在都用hibernate做的
那么推薦用hibernate shards,這個類似hibernate,學習成本低,能跟
hibernate兼容
目前國內有在hibernate? shards上封裝的成功案例,
缺點是list查詢時遍歷所有數據片,而不是根據sql規則確定的數據片。
這個bug及在hibernate shards上如何擴展問題我已解決,附件是解決的架構圖,
需要源代碼的或詳細可以聯系我;
ibatis shards跟hibernate shards類似,也可借鑒本人所設計的架構
思想 歡迎有志之士詳聊
附:
一、hibernate shards
優點:
1、實現跟其他成熟框架的集成如spring
等
2、能利用公司現有的hibernate的技術優勢
3、目前國內有成功案例在hibernate? shards上封裝
的商業軟件
4、能夠快速開發
缺點:
1、暫不支持垂直分區
2、list查詢遍歷所有表分片