Laravel Memcache

dakata__92

Super Moderator
Колеги, имам един код на Laravel 6, който е качен на VPS-ка. С него се опитвам да направя кеширане на информация от заявка без да използвам "Query builder".
Код:
public function getMemcache(String $sql, Array $options = [])
    {
        if (!isset($sql) and !is_string($sql)) {
            throw new \Exception("No SQL string!");
        }
        $options['ttl'] = (isset($options['ttl']) and (int) $options['ttl']) ? $options['ttl'] : 3600;
        $options['key'] = isset($options['key']) ? $options['key'] : md5($sql);
        $options['reset'] = isset($options['reset']) ? true : false;
        $options['reset_all'] = isset($options['reset']) ? true : false;
        $options['ip'] = isset($options['ip']) ? $options['ip'] : false;
        self::$memcahe['sql'] = $sql;
        self::$memcahe['options'] = $options;
        if ($options['reset']) {
            cache()->forget($options['key']);
        }
        if ($options['reset_all']) {
            cache()->flush();
        }
        return cache()->remember($options['key'], $options['ttl'], function () {
            return self::getDb()::query(self::$memcahe['sql'], self::$memcahe['options']['ip']);
        });
    }

Така викам кода:
Код:
$memcacheOptions = [
                    'server_ip' => $servers[$i]['server_ip'],
                    'ttl' => 3600
];
$buffers[$i] = self::getMemcache("SELECT COUNT(id) as count FROM table ", $memcacheOptions)->fetch_object()->count;

Проблема ми е, че не успявам да направя кеширането. Някъде бъркам концептуално в използването на кеширането или някъде по опциите я на сървъра, я на Ларавел трябва да пипна? Получавам информация от базата, но когато направя в нея промяна ръчно през едитора, веднага се отразява и в системата, а не би трябвало. По принцип трябва да ми покаже кешираната НЕ променена стойност, докато изтече времето и. Дали е защото изполвам "remember"?
 
Fakeheal каза:
Нямам решение на проблема ти и мнението ми е оффтопик, за което се извинявам.

Защо го правиш това и защо го правиш така?

Две отделни системи се използват. Ларавел е само за админ панела. В случая поради използването на външен клас за управление на базата с данни, то се налага да създам и кеширане на някои заявки. Ползвам вградената функционалност на Ларавел за това, но някъде нещо не ми се получава или с настройките на рамката и сървъра, или с кода, който съм дал.
 
Къде се намира кода, който си показал? Сигурен ли си, че всички неща на рамката са заредили преди да извикаш този код? Как точно си добавил този външен клас за управление на базата данни?
 
Fakeheal каза:
Къде се намира кода, който си показал? Сигурен ли си, че всички неща на рамката са заредили преди да извикаш този код? Как точно си добавил този външен клас за управление на базата данни?

Кода се намира в модел. Всичко е заредено.

Проблема не е в класът, който ползвам, а явно в кода който съм дал. Дали някоя от настройките на Ларавел не съм съобразил да настроя или нещо на сървъра свързано с кеширането?
 
Ами дай да видим как си конфигурирал Ларавел да използва memcached.
Само едно хранилище имаш?
Получаваш ли грешки?
Дебъгна ли Memcached да видиш дали съдържа нещо?
Ако няма стойности, значи проблема е в конфигурацията или сървъра.

Знаеш ли как е конфигуриран memcached?
 
Revelation каза:
Ами дай да видим как си конфигурирал Ларавел да използва memcached.
Само едно хранилище имаш?
Получаваш ли грешки?
Дебъгна ли Memcached да видиш дали съдържа нещо?
Ако няма стойности, значи проблема е в конфигурацията или сървъра.

Знаеш ли как е конфигуриран memcached?
По принцип нищо не съм пипал, още. Тоест си е стандартна инсталация на Ларавел. Ако знаеш къде да видя и проверя дали всички чекове са пуснати, сподели. Нямам грешки, връща ми инстанциите, просто ми актуализира нещата постоянно.
 
В документацията пише:

Код:
If you are using the Memcached driver, items that are stored "forever" may be removed when the cache reaches its size limit.

В твоя код какво е
Код:
self::$memcache
и AFAIK memcached автоматично изтрива "стари" записи.

* "стари" - stale - по негова дефиниция

Можеш ли да дадеш примерен (и орязан модел) от апа ти?

PS: може би тъпа идея, но:
Код:
dd(cache()->driver());
какво ти връща? :D
 
dakata__92 каза:
Revelation каза:
Ами дай да видим как си конфигурирал Ларавел да използва memcached.
Само едно хранилище имаш?
Получаваш ли грешки?
Дебъгна ли Memcached да видиш дали съдържа нещо?
Ако няма стойности, значи проблема е в конфигурацията или сървъра.

Знаеш ли как е конфигуриран memcached?
По принцип нищо не съм пипал, още. Тоест си е стандартна инсталация на Ларавел. Ако знаеш къде да видя и проверя дали всички чекове са пуснати, сподели. Нямам грешки, връща ми инстанциите, просто ми актуализира нещата постоянно.

Отвори .env файла и ми дай частта, където са CACHE_* конфигурациите. Ако там е оставено на file, а си конфигурирал memcached в config/cache.php файла, е много вероятно в момента да имаш 2 store-a.

Също, ако там си го настройл правилно, върни драйвъра на file и опитай отново, да видиш дали ще се оправи. Ако се оправи, значи Memcached сървъра се дъни някъде.
Виж версията на Memcached в phpinfo(). Също, ако използваш PHP 7.3 ти трябва версия на библиотеката поне 3.1.0 (3.1.3 за PHP 7.4).
Ако не са съвместими най-вероятно дава грешка, но не боли да провериш.

Конфигурацията на memcached по принцип е в /etc/memcached.conf.

Ако имаш възможност, по принцип ти препоръчвам да минеш на Redis.
 
Не съм на машината тази вечер, но утре ще разгледам и изтествам предложенията Ви.
Код:
self::$memcache
Това е просто глобална променлива / масив, която ползвам за да пренеса инфото от метода в анонимната функция на "remember". Кода е писан много набързо и не съм оптимизирал нещата, но просто при тестовете не се държеше, както се очакваше да стане. Ще разгледам утре и конфигурацията, като се надявам колегите или аз да не сме пипали нещо, без да се осетим и да е повлияло.

Не съм ползвал Redis, ще прочета за него.
 
dakata__92 каза:
Код:
self::$memcache
Това е просто глобална променлива / масив, която ползвам за да пренеса инфото от метода в анонимната функция на "remember".

Използвай use на анонимната функция.

Код:
return cache()->remember($options['key'], $options['ttl'], function () use ($sql, $options) {
    return self::getDb()::query($sql, $options['ip']);
});
 
Revelation каза:
dakata__92 каза:
Код:
self::$memcache
Това е просто глобална променлива / масив, която ползвам за да пренеса инфото от метода в анонимната функция на "remember".

Използвай use на анонимната функция.

Код:
return cache()->remember($options['key'], $options['ttl'], function () use ($sql, $options) {
    return self::getDb()::query($sql, $options['ip']);
});
То като цяло кода ще търпи промяна, само да го подкарам коретно.
 
Малко информация от снощните въпроси:

dd(cache()->driver());
Код:
Repository {#218 ▼
  #store: FileStore {#217 ▼
    #files: Filesystem {#161}
    #directory: "/var/www/admin/storage/framework/cache/data"
  }
  #events: Dispatcher {#35 ▼
    #container: Application {#2 ▶}
    #listeners: array:6 [▶]
    #wildcards: []
    #wildcardsCache: array:25 [▶]
    #queueResolver: Closure() {#36 ▶}
  }
  #default: 3600
}

phpinfo();
Код:
PHP Version 7.3.1
Memcache Version 	3.0.9-dev

.env
Код:
CACHE_DRIVER=file

config/cache.php
Код:
<?php

use Illuminate\Support\Str;

return [

    /*
    |--------------------------------------------------------------------------
    | Default Cache Store
    |--------------------------------------------------------------------------
    |
    | This option controls the default cache connection that gets used while
    | using this caching library. This connection is used when another is
    | not explicitly specified when executing a given caching function.
    |
    | Supported: "apc", "array", "database", "file",
    |            "memcached", "redis", "dynamodb"
    |
    */

    'default' => env('CACHE_DRIVER', 'file'),

    /*
    |--------------------------------------------------------------------------
    | Cache Stores
    |--------------------------------------------------------------------------
    |
    | Here you may define all of the cache "stores" for your application as
    | well as their drivers. You may even define multiple stores for the
    | same cache driver to group types of items stored in your caches.
    |
    */

    'stores' => [

        'apc' => [
            'driver' => 'apc',
        ],

        'array' => [
            'driver' => 'array',
        ],

        'database' => [
            'driver' => 'database',
            'table' => 'cache',
            'connection' => null,
        ],

        'file' => [
            'driver' => 'file',
            'path' => storage_path('framework/cache/data'),
        ],

        'memcached' => [
            'driver' => 'memcached',
            'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
            'sasl' => [
                env('MEMCACHED_USERNAME'),
                env('MEMCACHED_PASSWORD'),
            ],
            'options' => [
                // Memcached::OPT_CONNECT_TIMEOUT => 2000,
            ],
            'servers' => [
                [
                    'host' => env('MEMCACHED_HOST', '127.0.0.1'),
                    'port' => env('MEMCACHED_PORT', 11211),
                    'weight' => 100,
                ],
            ],
        ],

        'redis' => [
            'driver' => 'redis',
            'connection' => 'cache',
        ],

        'dynamodb' => [
            'driver' => 'dynamodb',
            'key' => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
            'table' => env('DYNAMODB_CACHE_TABLE', 'cache'),
        ],

    ],

    /*
    |--------------------------------------------------------------------------
    | Cache Key Prefix
    |--------------------------------------------------------------------------
    |
    | When utilizing a RAM based store such as APC or Memcached, there might
    | be other applications utilizing the same cache. So, we'll specify a
    | value to get prefixed to all our keys so we can avoid collisions.
    |
    */

    'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache'),

];
 
Смени в .env:

Код:
CACHE_DRIVER=memcached

и после пусни:

Код:
php artisan config:clear

или там, както е, за да презареди config-a. После виж дали ти се е сменил drive-a на cache-a oт file на memcached.

Код:
dd(cache()->drive())
 
Fakeheal каза:
Смени в .env:

Код:
CACHE_DRIVER=memcached

и после пусни:

Код:
php artisan config:clear

или там, както е, за да презареди config-a. После виж дали ти се е сменил drive-a на cache-a oт file на memcached.

Код:
dd(cache()->drive())
Сменят се нещата:
Код:
#store: MemcachedStore {#219 ▼
    #memcached: Memcached {#218 ▶}
    #prefix: "name_admin_cache:"
    #onVersionThree: true
  }
  #events: Dispatcher {#35 ▶}
  #default: 3600
}
 
Тръгнаха ли нещата сега?

Също, ако memcached сървъра използва друго IP и порт, ги добави в .env файла.

Код:
MEMCACHED_HOST=...
MEMCACHED_PORT=...

Също имай в предвид следното от предния ми пост:

Revelation каза:
Също, ако използваш PHP 7.3 ти трябва версия на библиотеката поне 3.1.0 (3.1.3 за PHP 7.4)

Ако това е memcache lib, а не memcached, ти трябва memcache v4+.
 
Revelation каза:
Тръгнаха ли нещата сега?

Също, ако memcached сървъра използва друго IP и порт, ги добави в .env файла.

Код:
MEMCACHED_HOST=...
MEMCACHED_PORT=...

Също имай в предвид следното от предния ми пост:

Revelation каза:
Също, ако използваш PHP 7.3 ти трябва версия на библиотеката поне 3.1.0 (3.1.3 за PHP 7.4)

Ако това е memcache lib, а не memcached, ти трябва memcache v4+.
Утре с колегата, ще ъпгрейднем версията и ще тествам пак.
 

Горе