中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

當網站性能遭遇瓶頸的時候

發布時間:2020-04-06 11:21:05 來源:網絡 閱讀:8584 作者:七彩極 欄目:web開發

一、問題描述
1.起源。我在做一個在線考試系統的項目中,希望用戶回答的每一道題都有相應的記錄:一是記錄每道題的正確、錯誤的次數;二是記錄用戶每個錯題,用來形成用戶的錯題集。
當網站性能遭遇瓶頸的時候
2.實現。由于考試的試卷中有不定數量的試題,所以我使用循環在判斷用戶回答是否正確,并在循環中記錄數據,并寫入數據庫。
當網站性能遭遇瓶頸的時候
3.瓶頸。由于每提交一個答卷,就會產生數十次或更多的數據庫寫入或更新的操作,因此會耗費大量的時間。
二、問題分析

1.由于每道題都要被記錄兩次:一次是更新試題對錯的次數,二次是記錄到錯題集中,如果每個試卷有20道試題,那么每個答卷就要進行40次數據庫操作,導致數據庫壓力很大。
2.由于每個試題都是不同的數據庫記錄,因此難以批量更新(有的是新增記錄,有的是更新記錄)。
3.如果大量用戶并發提交,那么服務器就可能崩潰,速度緩慢。雖然我的小網站平時沒有那么多人來光顧,但我自己開發的系統總不能最終成為不可用的廢品吧,所以必須優化下!
三、解決思路和方案

1.因為有大量數據庫操作,所以我首先考慮到的是使用redis來提升性能。
2.由于更新數據的操作既有新增記錄,又有更新記錄,所以必須把更新操作和操作從邏輯上分離出來。
3.我使用的是thinkphp框架開發,模型層自帶批量新增的函數addAll(),因此,新增數據的操作就用它解決了;然后通過網上搜索或自己編寫一個函數,拼裝批量更新sql語句,形如如下的語句結構:
UPDATEcategories SET
display_order = CASE id
WHEN 1 THEN 3
WHEN 2 THEN 4
WHEN 3 THEN 5
END,
title = CASE id
WHEN 1 THEN 'New Title 1'
WHEN 2 THEN 'New Title 2'
WHEN 3 THEN 'New Title 3'
END
WHERE id IN(1,2,3)

4.通過redis的hash表來記錄要更新或新增的數據,在適當的時機,觸發數據庫操作,通過php操作redis的數據,執行成功后就刪除那些redis數據,從而解決瓶頸問題。

附:以下是對試題對錯記錄的優化,對于用于錯題集的優化代碼類似,因此只展示前者的代碼了。
5.redis記錄過程:
$check ? $field = 'r' : $field = 'w';//檢查對錯
$redis = new \Redis();
$redis->connect('127.0.0.1',6379);
$redis->hIncrBy(‘qid_check_log’,'qid.'.$qid.'.'.$field,1); //鍵值累加1

6.把redis數據轉存到mysql中:
$redis = new \Redis();
$redis->connect('127.0.0.1',6379);
$data_cache = $redis -> hGetAll(‘qid_check_log’);
$temp = array(); //待更新的數據
$i = 0;

//要增加的數據
foreach($data_cache as $key=>$num){
    $arr = explode('.',$key);
    $qid = $arr[1];
    $field = $arr[2];
    $temp[$i]['qid'] = $qid;
    $ids[] = $qid;//需要更新的試題id
    $temp[$i][$field] = $num;
    $redis -> hDel($qid_check_log,$key);
    $i++;
}

if(empty($ids)) return true;//如果沒有更新,則直接返回

//獲取原來的數據
$map['qid'] = array('in',$ids);
$old_data = M('questionlog') -> where($map) -> select();
$old_data2 = array();
foreach($old_data as $one){
    $old_data2[$one['qid']] = $one;
}
unset($old_data);

//合并數據
foreach($temp as &$one){
    if(isset($one['r'])){
        $one['r'] = $old_data2[$one['qid']]['r'] + $one['r'];
    }else{
        $one['r'] = $old_data2[$one['qid']]['r'];
    }

    if(isset($one['w'])){
        $one['w'] = $old_data2[$one['qid']]['w'] + $one['w'];
    }else{
        $one['w'] = $old_data2[$one['qid']]['w'];
    }
}

$re = batch_update('questionlog',$temp,'qid');//執行批量更新

后記:其實當初我在編寫程序的時候沒有設計好,如果設計得合理的化,也許不需要redis也能完成這個優化,不過,也正好因為這個機會,讓我在項目中真正用到了redis,感受到了它的速度優勢,哈哈!
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

扬州市| 奉贤区| 建平县| 宁明县| 肃南| 保靖县| 会昌县| 芮城县| 大冶市| 通渭县| 湖州市| 武陟县| 鄯善县| 海原县| 城固县| 溧阳市| 炎陵县| 湛江市| 新田县| 渑池县| 亳州市| 蚌埠市| 胶州市| 安福县| 荥经县| 漳州市| 凤凰县| 杭锦后旗| 樟树市| 建宁县| 阿图什市| 芷江| 岗巴县| 黔东| 保康县| 南华县| 麻城市| 孟村| 桑植县| 无锡市| 武隆县|