Laravel 中緩存驅動的速度比較


緩存是web開發中重要的一部分,我相信很多人和我一樣,經常忽略這個問題。 隨着工作經驗的累積,我已經意識到緩存是多么的重要,這里我通過 Scotch 來解釋一下它的重要性。

通過觀察發現,Scotch每天按照計划發布文章,然而,上一次發布文章的24小時內,新的文章不會被放出,因此,登陸頁面上的數據將保持24小時不變。 換句話說,在24小時內( 更准確的說是22-23個小時)向數據庫請求文章數據是沒有意義的。

緩存可以很好的解決這個問題,當遇到一個頁面請求時,我們可以把結果緩存22個小時,只要在這個時間內通過控制器請求的數據,都是緩存中的數據,直到緩存超時。

下面我們來看看Laravel 中緩存的基本用法,然后看一個簡單的例子,試試緩存到底能帶來多大的加速。

在 Laravel 中緩存的基本用法

Laravel 使得我們可以輕松地轉換出我們想要生成緩存的方式。我們很容易修改緩存驅動方式。只需到 config / cache.php 來查看可用的驅動程序:

  • apc
  • array
  • database
  • file
  • memcached
  • redis

你可以在 .env 文件中修改緩存驅動:

CACHE_DRIVER=file

你可以繼續嘗試修改它們而不用擔心配置,因為它默認驅動是 file

Cache facade 暴露了很多靜態方法來創建,更新,獲取,刪除和檢查緩存內容的存在。讓我們在構建演示應用程序之前先了解一下這些方法。

建立/更新緩存值

我們使用 put() 方法來新增或更新緩存值。該方法必須使用 3 個參數:

  • 鍵名
  • 鍵值
  • 過期時間 單位分鍾

例如:

Cache::put('key', 'value', 10);

鍵名 是緩存的唯一標識,需要時要用它來獲取值。

此外,我們也可以用 remember() 方法自動獲取和更新一個緩存值。該方法首先檢查 鍵名 是否存在,如果已經創建則返回結果。否則它會創建新的 鍵名 ,並用閉包返回結果進行賦值,就象下面:

Cache::remember('articles', 15, function() {
    return Article::all();
});

參數 15 是要緩存的分鍾數。這樣的話,我們甚至根本不必檢查緩存是否過期。Laravel 不僅會替我們打理,而且會獲取或重新生成該緩存,不需要我們顯式地告訴它如何操作。

檢索緩存值

緩存的值可以通過 get() 方法去獲取,這個方法接受一個參數 key :

Cache::get('key');

檢查是否已存在key

有時候在更新或者取回緩存值之前判斷這個緩存的key是否存在是很有必要的,使用 has() 方法就可以實現:

if (Cache::has('key')){
    Cache::get('key');
} else {
    Cache::put('key', $values, 10);
}

刪除緩存值

刪除緩存值可以用 forget() 方法並把需要刪除的 key 作為參數傳進去:

Cache::forget('key');

我們也可以檢索緩存值並刪除它。我喜歡把這個稱為一次性緩存:

$articles = Cache::pull('key');

我們還可以使用以下命令在緩存過期前就把所有緩存清楚掉:

php artisan cache:clear

一個例子

這是一個簡單的演示,主要是為了說明是否使用緩存對請求響應所需要時間的影響,為了讓你能更直接的了解,我建議你跟着教程自己來 構建 一個 Laravel 例子。

模型和表遷移

使用下面命令新建一個 Article 模型:

php artisan make:model Article -m

-m 參數會自動創建一個 migration ,所以無需再使用 create migration 命令了,這個命令會創建 App/Article.php 和  database/migrations/xxxx_xx_xx_xxxxxx_create_articles_table.php 文件。

修改你的 migration 文件並添加以下兩行:

public function up() {
    Schema::create('articles', function (Blueprint $table) {
        $table->increments('id');

        // add the following
        $table->string("title");
        $table->string("content");

        $table->timestamps();
    });
}

然后我們就可以用以下命令遷移我們的數據庫了:

php artisan migrate

填充數據庫

接下來我們需要填充文章的數據庫表,在 database/seeds/DatabaseSeeder.php 中,修改  run() 如下所示:

public function run() {
    Model::unguard();

    // use the faker library to mock some data
    $faker = Faker::create();

    // create 30 articles
    foreach(range(1, 30) as $index) {
        Article::create([
            'title' => $faker->sentence(5),
            'content' => $faker->paragraph(6)
        ]);
    }

    Model::reguard();
}

Laravel中包含 Faker 庫用以快速生成假數據,我們可以使用PHP的 range() 方法去生成30條假數據。

接下來我們就可以通過這條 artisan 命令去填充數據庫了:

php artisan db:seed

創建文章控制器

接下來,我們可以創建一個處理請求和緩存的控制器,首先它是空的:

php artisan make:controller ArticlesController

...然后我們增加一個路由 app/Http/routes.php 指向這個文章控制器的 index 方法:

Route::group(['prefix' => 'api'], function() {

    Route::get('articles', 'ArticlesController@index');

});

現在我們的數據庫都是用樣本數據建立起來的,我們可以進行測試了。

未使用緩存的響應

讓我們看看我們傳統的控制器方法是什么樣的,沒有緩存,處理響應需要多長時間,在 index() 方法中,返回文章的資源數據:

public function index() {
    $articles = Articles::all();
    return response()->json($articles);
}

你也可以使用 Postman 去請求(http://localhost/api/articles) 或者直接用瀏覽器打開,你就可以看到如下所示。

請注意在本地開發服務器上完成此請求所花費的時間。

從緩存中返回的響應

現在讓我們嘗試使用緩存,看看數據響應所花費的時間是否會有顯着差異。修改 index()方法為:

 public function index() {
    $articles = Cache::remember('articles', 22*60, function() {
        return Article::all();
    });
    return response()->json($articles);
}

現在我們使用 remember() 方法緩存了文章,緩存時間為 22 小時,再次運行並觀察所花費的時間,可以看我的截圖:

結果和建議

在我的標准開發環境中測試得出,使用緩存時產生響應所需的時間比沒有使用的時候要少:

未使用緩存

Server Hits Time
1st 4478ms
2nd 4232ms
3rd 2832ms
4th 3428ms
Avg 3742ms

使用緩存 (File 驅動)

Server Hits Time
1st 4255ms
2nd 3182ms
3rd 2802ms
4th 3626ms
Avg 3466ms

使用緩存 (Memcached 驅動)

Server Hits Time
1st 3626ms
2nd 566ms
3rd 1462ms
4th 1978ms
Avg 1908ms 😃

使用緩存 (Redis 驅動)

這里需要通過 composer 安裝 predis/predis 包

Server Hits Time
1st 3549ms
2nd 1612ms
3rd 920ms
4th 575ms
Avg 1664ms 😃

是不是很酷呢?這里有兩點需要注意:

  1. 即使使用了緩存,第一次請求響應還是需要比較多的時間,因為當第一次請求的時候緩存里面還是空的。
  2. 與 file 驅動相比,Memcached 和 Redis 的速度更快,所以建議在項目較大時使用外部緩存驅動。

結論

使用文件、數據庫作為驅動,兩者在速度上沒有很明顯的區別。但是如果我們使用第三方服務作為驅動, 可以很明顯地看到性能提升。所以投資高速緩存是值得的。

更多現代化 PHP 知識,請加入 PHP / Laravel 知識社區 一起學習成長吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM