qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          關于 Java Web 項目性能提升的一些思路

           使用 Nginx 作為前端接入
            用 Nginx 進行動靜分離。這個不用多講,新浪、網易、淘寶、騰訊等巨頭的使用已經說明了一切。
            保持最簡單的架構
            遵守 KISS 原則(Keep it simple and stupid)。盡量不要考慮項目外的重用。過多的考慮項目外的重用,必然會增加項目的復雜度。避免過度集成,讓每個模塊只做自己的事,這對于日后的維護和模塊復用都有好處。
            精心設計緩存處理、毫不吝嗇代碼(對象、列表、片段)
            對于門戶網站的首頁來說,往往可能會有近百個 SQL。用戶并發上去以后,光首頁就足以讓服務器 down 掉。緩存不但有利于降低負載,而且還能提高響應速度。
            調整使用聚集索引
            對于每個表來講,聚集索引只有一個,利用好了,查詢速度會有意想不到的提升效果。
            以 MySql 為例,InnoDB選取聚集索引參照列的順序是
            1. 如果聲聲明了主鍵(primary key),則這個列會被做為聚集索引;
            2. 如果沒有聲明主鍵,則會用一個唯一且不為空的索引列做為主鍵,成為此表的聚集索引;
            3. 上面二個條件都不滿足,InnoDB會自己產生一個虛擬的聚集索引。
          CREATE TABLE `timeline_raw` (
          `rawId` bigint(20) NOT NULL AUTO_INCREMENT,
          `uid` bigint(20) DEFAULT NULL,
          `did` bigint(20) DEFAULT NULL,
          `channelId` char(1) NOT NULL DEFAULT '1' COMMENT '1:qvga; 2:720p',
          `fileId` bigint(20) DEFAULT NULL,
          `sectionId` bigint(20) DEFAULT NULL,
          `headerFilePath` varchar(120) DEFAULT NULL,
          `startTime` bigint(20) DEFAULT NULL,
          `endTime` bigint(20) DEFAULT NULL,
          `updateTime` datetime DEFAULT NULL,
          `createTime` datetime DEFAULT NULL,
          PRIMARY KEY (`rawId`),
          KEY `index_uid_did_startTime` (`uid`,`did`,`startTime`) USING BTREE,
          KEY `index_uid_did_endTime` (`uid`,`did`,`endTime`) USING BTREE,
          KEY `index_time` (`startTime`) USING BTREE,
          KEY `index_uid_did_fileId` (`uid`,`did`,`sectionId`) USING BTREE,
          KEY `index_sectionId` (`sectionId`)
          ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
            這個表有四個索引:主鍵 rawId、sectionId、`uid`,`did`、startTime。

           項目的 iBatis2 中有這樣一條查詢語句:
          <select id="getRawFileList" parameterClass="java.util.HashMap" resultClass="com.defonds.mysql.raw.entity.TimelineRaw">
          SELECT * FROM timeline_raw_
          WHERE uid=#uid#
          AND did=#did#
          AND channelId=#channelId#
          <isNotNull  property="sectionId"> AND sectionId = #sectionId#</isNotNull>
          AND
          (
          (startTime BETWEEN #startTime# and #endTime#)
          OR
          (endTime BETWEEN #startTime# and #endTime#)
          OR
          (
          <![CDATA[
          startTime<=#startTime#
          ]]>
          AND
          <![CDATA[
          endTime>=#endTime#
          ]]>
          )
          )
          ORDER BY startTime;
          </select>
            根據實際業務向 timeline_raw 表注入一千萬條數據,進行模擬測試(參考《sql 性能測試例子》),發現 getRawFileList 的執行平均時間為 160 ms 以上。這是不能接受的。
            考慮到實際業務中對于主鍵 rawId 查詢條件甚少,我們把rawId主鍵索引取消掉,改為唯一約束,卻把sectionId+startTime+endTime作為主鍵(業務上能夠保證其唯一性,根據InnoDB索引規則,這個索引將成為我們新表的聚集索引)。然后把sectionId、startTime兩個索引也取消掉,僅保留`uid`,`did`索引。
            這樣子,我們新表的索引實際上只有兩個了:一個聚集索引(sectionId+startTime+endTime)一個非聚集索引(`uid`,`did`)。
            再次進行模擬測試,同樣的數據、數據量,同樣的查詢結果集,getRawFileList 執行平均時間已經降到了 11 ms。結果是令人振奮的,不是么?
            使用 /dev/shm 來存儲緩存的磁盤文件
            在網站運維中,利用好了這一點,往往有意想不到的收獲。以 tomcat 為例,可以通過修改 catalina.sh 中的 CATALINA_TMPDIR 值的路徑來將緩存設置為 /dev/shm。
            以 OSC 為例,他們就是純 Java 寫的,部署在 tomcat 下。在長時間的在線運行之后,管理員發現網站響應速度奇慢,服務器負載正常,又找不出是哪里的問題。后來 df 一下,發現 tomcat 臨時目錄下的文件足足有 8G 之多,原來是 CPU 等待磁盤操作造成響應速度加長。于是他們將臨時目錄映射到 /dev/shm,網站響應速度從此奇快。
            分析系統中每一個 SQL 的執行效率
            以 MySql 為例,對于每個 SQL 最好都 explain 一下。對于有明顯效率問題的,通過 sql 優化、調索引等方法進行改進。
            健康慢查詢日志,檢查所有執行超過 100 毫秒的 SQL
            對于上線了的項目,健康慢查詢日志,檢查所有執行超過 100 毫秒的 SQL,看看有沒有優化余地。對于沒有上線的項目,可以進行場景模擬對嫌疑 SQL,或者對頻繁使用的 SQL 進行性能測試,統計它們執行時間,得出平均值,畫出曲線分析圖,對于單表千萬數據,執行時間超過 50ms 的 SQL 要重點關注。參考《sql 性能測試例子》。

          posted on 2013-12-23 09:59 順其自然EVO 閱讀(701) 評論(0)  編輯  收藏 所屬分類: 數據庫

          <2013年12月>
          24252627282930
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 永兴县| 泉州市| 英德市| 丹阳市| 林口县| 都兰县| 黔江区| 泰州市| 临澧县| 阳东县| 岳池县| 简阳市| 正安县| 且末县| 康马县| 惠东县| 丘北县| 雷波县| 宁明县| 平昌县| 诸暨市| 平乐县| 信丰县| 博野县| 吉木萨尔县| 罗平县| 濮阳县| 新河县| 天等县| 寿宁县| 隆林| 德州市| 云南省| 讷河市| 陆川县| 嘉峪关市| 二连浩特市| 岳普湖县| 杭锦后旗| 肇东市| 鱼台县|