笨笨的思想片斷

          零碎片斷,雜七雜八。
          posts - 25, comments - 79, trackbacks - 0, articles - 0

          減少全局競爭性同步,提高應用的垂直擴展能力

          垂直擴展,簡單的說,是當單一系統硬件升級擴展時,如增加CPU,內存,應用程序能夠隨之線性提高業務處理能力。
          多線程是服務端 Java 應用的標準處理方式,其優點不用贅述。本文要討論的是,如何在設計階段降低多線程之間的競爭性同步開銷。

          假設一個Web應用,需要為當前用戶維護在線用戶信息。此用戶信息列表會放在 Application 范圍的一個 Map 中,那么我們增加或刪除一個在線用戶的操作會是這樣:。
          Map clientMap = ...// from Application Context
          synchronized(clientMap){
           clientMap.put(clientId,clientObject);
          }
          這是一個典型的全局同步代碼,當并發線程增加時,這部分代碼就有可能會存在潛在垂直擴展瓶頸。

          最簡單解決辦法:用 ConcurrentHashMap。
          ConcurrentHashMap的多線程下的表現要比HashMap好的多,可以做到隨著線程數增長性能基本保持穩定。
          參見:http://www-128.ibm.com/developerworks/cn/java/j-jtp07233/index.html
          對 ConcurrentHashMap 的分析,參見:http://www-128.ibm.com/developerworks/cn/java/j-jtp08223/index.html


          在 ConcurrentMap/ConcurrentLinkedQueue 不能幫助我們的情況下,我們需要明確設計以避免全局競爭。
          基本原則是:
          1 預分配,降低爭用出現的頻率。
          2 降低鎖的粒度,將全局競爭變為局部競爭。

          預分配策略示例:
          對于一在線交易處理系統,需要為每個交易生成交易流水號,假設有多臺交易服務器按照集群方式配置,同時提供服務。那么需要在交易服務器之間進行同步,以保證交易流水號的正常增長。
          一種處理方式為:在數據庫中保存當前交易流水號的最高值,每臺機器一次預分配1000流水,內部采用線程同步進行分配,用完再從數據庫分配。這里數據庫充當了全局存儲和全局同步工具,如果每來一條交易,就訪問一次數據庫,考慮到數據庫同步和事務的負擔,這里會成為嚴重的性能瓶頸。

          降低鎖粒度策略示例:
          1 ConcurrentHashMap 本身就是個很好的模范。它采用32顆鎖,來代替普通 HashMap 的單顆對象鎖。
          2 對于數據庫中并發大的表,可以考慮將表級鎖改為行級鎖,提高并發性。

          暫時想不起來示例,有空再補

          Feedback

          # re: 減少全局競爭性同步,提高應用的垂直擴展能力  回復  更多評論   

          2005-12-13 00:07 by 非魚
          笨笨,有沒有興趣加入“架構師之家”啊?

          # re: 減少全局競爭性同步,提高應用的垂直擴展能力  回復  更多評論   

          2005-12-13 09:32 by 笨笨
          這個,其實我性格疏懶;
          怕難以擔此名,反誤了大事。
          主站蜘蛛池模板: 清涧县| 侯马市| 北宁市| 合川市| 威宁| 石棉县| 互助| 塘沽区| 安徽省| 彰化市| 邢台市| 墨玉县| 佛坪县| 南江县| 庆元县| 加查县| 都江堰市| 晋城| 海原县| 潜江市| 通榆县| 贡山| 惠安县| 正蓝旗| 筠连县| 商都县| 普宁市| 山丹县| 东山县| 丰顺县| 收藏| 辽源市| 博罗县| 仁怀市| 黄龙县| 仲巴县| 剑河县| 偃师市| 建平县| 沙河市| 紫阳县|