Table des matières
Cache失效后的拥堵问题
Multiget的无底洞问题
Nagle和DelayedAcknowledgment的延迟问题
Maison base de données tutoriel mysql Memcached二三事儿

Memcached二三事儿

Jun 07, 2016 pm 04:29 PM
memcached absolu

Memcached绝对称得上是NoSQL老兵!可惜随着时间的推移,Redis等后起之秀羽翼渐丰,Memcached相比之下已呈颓势。那我们还用不用学习它?答案是肯定的!毕竟仍然有很多项目依赖着它,如果忽视它,一旦出了问题就只有干瞪眼的份儿了。 网络上关于Memcached的资

Memcached绝对称得上是NoSQL老兵!可惜随着时间的推移,Redis等后起之秀羽翼渐丰,Memcached相比之下已呈颓势。那我们还用不用学习它?答案是肯定的!毕竟仍然有很多项目依赖着它,如果忽视它,一旦出了问题就只有干瞪眼的份儿了。

网络上关于Memcached的资料可以说是浩如烟海,其中不乏一些精彩之作,比如说由爱好者翻译的「Memcached全面剖析」系列文章,在中文社区广为流传,虽然已经是几年前的文章了,但是即便现在读起来,依然感觉收获良多,推荐大家多看几遍:

  1. Memcached的基础
  2. 理解Memcached的内存存储
  3. Memcached的删除机制和发展方向
  4. Memcached的分布式算法
  5. Memcached的应用和兼容程序

当然,官方Wiki永远是最权威的资料,即便是里面的ReleaseNotes也不要放过。

实际应用Memcached时,我们遇到的很多问题都是因为不了解其内存分配机制所致,下面就让我们以此为开端来开始Memcached之旅吧!

为了规避内存碎片问题,Memcached采用了名为SlabAllocator的内存分配机制。内存以Page为单位来分配,每个Page分给一个特定长度的Slab来使用,每个Slab包含若干个特定长度的Chunk。实际保存数据时,会根据数据的大小选择一个最贴切的Slab,并把数据保存在对应的Chunk中。如果某个Slab没有剩余的Chunk了,系统便会给这个Slab分配一个新的Page以供使用,如果没有Page可用,系统就会触发LRU机制,通过删除冷数据来为新数据腾出空间,这里有一点需要注意的是:LRU不是全局的,而是针对Slab而言的。

一个Slab可以有多个Page,这就好比在古代一个男人可以娶多个女人;一旦一个Page被分给某个Slab后,它便对Slab至死不渝,犹如古代那些贞洁的女人。但是女人的数量毕竟是有限的,所以一旦一些男人娶得多了,必然另一些男人就只剩下咽口水的份儿,这在很大程度上增加了社会的不稳定因素,于是乎我们要解放女性。

好在Memcached已经意识到解放女性的重要性,新版本中Page可以调配给其它的Slab:

shell> memcached -o slab_reassign,slab_automove
Copier après la connexion

换句话说:女人可以改嫁了!这方面,其实Memcached的儿子Twemcache革命得更彻底,他甚至写了一篇大字报,以事实为依据,痛斥老子的无能,有兴趣的可以继续阅读:Random Eviciton vs Slab Automove。

了解Memcached内存使用情况的最佳工具是:Memcached-tool。如果我们发现某个Slab的Evicted不为零,则说明这个Slab已经出现了LRU的情况,这通常是个危险的信号,但也不能一概而论,需要结合Evict_Time来做进一步判断。

在Memcached的使用过程中,除了会遇到内存分配机制相关的问题,还有很多稀奇古怪的问题等着你呢,下面我选出几个有代表性的问题来逐一说明:

Cache失效后的拥堵问题

通常我们会为两种数据做Cache,一种是热数据,也就是说短时间内有很多人访问的数据;另一种是高成本的数据,也就说查询很很耗时的数据。当这些数据过期的瞬间,如果大量请求同时到达,那么它们会一起请求后端重建Cache,造成拥堵问题,就好象在北京上班做地铁似的,英文称之为:stampeding herd,老外这里的用词还是很形象的。

一般有如下几种解决思路可供选择:

首先,我们可以主动更新Cache。前端程序里不涉及重建Cache的职责,所有相关逻辑都由后端独立的程序(比如CRON脚本)来完成,但此方法并不适应所有的需求。

其次,我们可以通过加锁来解决问题。以PHP为例,伪代码大致如下:

<?php function query()
{
    $data = $cache->get($key);
    if ($cache->getResultCode() == Memcached::RES_NOTFOUND) {
        if ($cache->add($lockKey, $lockData, $lockExpiration)) {
            $data = $db->query();
            $cache->set($key, $data, $expiration);
            $cache->delete($lockKey);
        } else {
            sleep($interval);
            $data = query();
        }
    }
    return $data;
}
?>
Copier après la connexion

不过这里有一个问题,代码里用到了sleep,也就是说客户端会卡住一段时间,就拿PHP来说吧,即便这段时间非常短暂,也有可能堵塞所有的FPM进程,从而使服务中断。于是又有人想出了柔性过期的解决方案,所谓柔性过期,指的是设置一个相对较长的过期时间,或者干脆不再直接设置数据的过期时间,取而代之的是把真正的过期时间嵌入到数据中去,查询时再判断,如果数据过期就加锁重建,如果加锁失败,不再sleep,而是直接返回旧数据,以PHP为例,伪代码大致如下:

<?php function query()
{
    $data = $cache->get($key);
    if (isset($data['expiration']) && $data['expiration'] add($lockKey, $lockData, $lockExpiration)) {
            $data = $db->query();
            $data['expiration'] = $expiration;
            $cache->set($key, $data);
            $cache->delete($lockKey);
        }
    }
    return $data;
}
?>
Copier après la connexion

问题到这里似乎已经圆满解决了,且慢!还有一些特殊情况没有考虑到:设想一下服务重启;或者某个Cache里原本没有的冷数据因为某些情况突然转换成热数据;又或者由于LRU机制导致某些键被意外删除,等等,这些情况都可能会让上面的方法失效,因为在这些情况里就不存在所谓的旧数据,等待用户的将是一个空页面。

好在我们还有Gearman这根救命稻草。当需要更新Cache的时候,我们不再直接查询数据库,而是把任务抛给Gearman来处理,当并发量比较大的时候,Gearman内部的优化可以保证相同的请求只查询一次后端数据库,以PHP为例,伪代码大致如下:

<?php function query()
{
    $data = $cache->get($key);
    if ($cache->getResultCode() == Memcached::RES_NOTFOUND) {
        $data = $gearman->do($function, $workload, $unique);
        $cache->set($key, $data, $expiration);
    }
    return $data;
}
?>
Copier après la connexion

说明:如果多个并发请求的$unique参数一样,那么实际上Gearman只会请求一次。

Multiget的无底洞问题

Facebook在Memcached的实际应用中,发现了Multiget无底洞问题,具体表现为:出于效率的考虑,很多Memcached应用都已Multiget操作为主,随着访问量的增加,系统负载捉襟见肘,遇到此类问题,直觉通常都是通过增加服务器来提升系统性能,但是在实际操作中却发现问题并不简单,新加的服务器好像被扔到了无底洞里一样毫无效果。

为什么会这样?让我们来模拟一下案发经过,看看到底发生了什么:

我们使用Multiget一次性获取100个键对应的数据,系统最初只有一台Memcached服务器,随着访问量的增加,系统负载捉襟见肘,于是我们又增加了一台Memcached服务器,数据散列到两台服务器上,开始那100个键在两台服务器上各有50个,问题就在这里:原本只要访问一台服务器就能获取的数据,现在要访问两台服务器才能获取,服务器加的越多,需要访问的服务器就越多,所以问题不会改善,甚至还会恶化。

不过,作为被告方,Memcached官方开发人员对此进行了辩护:

请求多台服务器并不是问题的症结,真正的原因在于客户端在请求多台服务器时是并行的还是串行的!问题是很多客户端,包括Libmemcached在内,在处理Multiget多服务器请求时,使用的是串行的方式!也就是说,先请求一台服务器,然后等待响应结果,接着请求另一台,结果导致客户端操作时间累加,请求堆积,性能下降。

如何解决这个棘手的问题呢?只要保证Multiget中的键只出现在一台服务器上即可!比如说用户名字(user:foo:name),用户年龄(user:foo:age)等数据在散列到多台服务器上时,不应按照完整的键名(user:foo:name和user:foo:age)来散列的,而应按照特殊的键(foo)来散列的,这样就保证了相关的键只出现在一台服务器上。以PHP的 Memcached客户端为例,有getMultiByKey和setMultiByKey可供使用。

Nagle和DelayedAcknowledgment的延迟问题

老实说,这个问题和Memcached没有半毛钱关系,任何网络应用都有可能会碰到这个问题,但是鉴于很多人在写Memcached程序的时候会遇到这个问题,所以还是拿出来聊一聊,在这之前我们先来看看Nagle和DelayedAcknowledgment的含义:

先看看Nagle:

假如需要频繁的发送一些小包数据,比如说1个字节,以IPv4为例的话,则每个包都要附带40字节的头,也就是说,总计41个字节的数据里,其中只有1个字节是我们需要的数据。为了解决这个问题,出现了Nagle算法。它规定:如果包的大小满足MSS,那么可以立即发送,否则数据会被放到缓冲区,等到已经发送的包被确认了之后才能继续发送。通过这样的规定,可以降低网络里小包的数量,从而提升网络性能。

再看看DelayedAcknowledgment:

假如需要单独确认每一个包的话,那么网络中将会充斥着无数的ACK,从而降低了网络性能。为了解决这个问题,DelayedAcknowledgment规定:不再针对单个包发送ACK,而是一次确认两个包,或者在发送响应数据的同时捎带着发送ACK,又或者触发超时时间后再发送ACK。通过这样的规定,可以降低网络里ACK的数量,从而提升网络性能。

Nagle和DelayedAcknowledgment虽然都是好心,但是它们在一起的时候却会办坏事。下面我们举例说说Nagle和DelayedAcknowledgment是如何产生延迟问题的:

Nagle和DelayedAcknowledgment的延迟问题

Nagle和DelayedAcknowledgment的延迟问题

客户端需要向服务端传输数据,传输前数据被分为ABCD四个包,其中ABC三个包的大小都是MSS,而D的大小则小于MSS,交互过程如下:

首先,因为客户端的ABC三个包的大小都是MSS,所以它们可以耗无障碍的发送,服务端由于DelayedAcknowledgment的存在,会把AB两个包放在一起来发送ACK,但是却不会单独为C包发送ACK。

接着,因为客户端的D包小于MSS,并且C包尚未被确认,所以D包不会立即发送,而被放到缓冲区里延迟发送。

最后,服务端触发了超时阈值,终于为C包发送了ACK,因为不存在未被确认的包了,所以即便D包小于MSS,也总算熬出头了,可以发送了,服务端在收到了所有的包之后就可以发送响应数据了。

说到这里,假如你认为自己已经理解了这个问题的来龙去脉,那么我们尝试改变一下前提条件:传输前数据被分为ABCDE五个包,其中ABCD四个包的大小都是MSS,而E的大小则小于MSS。换句话说,满足MSS的完整包的个数是偶数个,而不是前面所说的奇数个,此时又会出现什么情况呢?答案我就不说了,留给大家自己思考。

知道了问题的原委,解决起来就简单了:我们只要设置socket选项为TCP_NODELAY即可,这样就可以禁用Nagle,以PHP为例:

<?php $memcached->setOption(Memcached::OPT_TCP_NODELAY, true);
?>
Copier après la connexion

如果大家意犹未尽,可以继续浏览:TCP Performance problems caused by interaction between Nagle’s Algorithm and Delayed ACK。

希望本文能让大家在使用Memcached的过程中少走一些弯路。相对于Memcached,其实我更喜欢Redis,从功能上看,Redis可以说是Memcached的超集,不过Memcached自有它存在的价值,即便已呈颓势,但是:老兵永远不死,只是慢慢凋零。

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

La technologie de mise en cache Memcached optimise le traitement des sessions en PHP La technologie de mise en cache Memcached optimise le traitement des sessions en PHP May 16, 2023 am 08:41 AM

Memcached est une technologie de mise en cache couramment utilisée qui peut améliorer considérablement les performances des applications Web. En PHP, la méthode de traitement de session couramment utilisée consiste à stocker le fichier de session sur le disque dur du serveur. Cependant, cette méthode n'est pas optimale car le disque dur du serveur deviendra l'un des goulots d'étranglement des performances. L'utilisation de la technologie de mise en cache Memcached peut optimiser le traitement des sessions en PHP et améliorer les performances des applications Web. Séance en PHP

Bibliothèque de mise en cache en PHP8.0 : Memcached Bibliothèque de mise en cache en PHP8.0 : Memcached May 14, 2023 am 08:16 AM

Bibliothèque de mise en cache en PHP8.0 : Memcached Avec le développement rapide d'Internet, les applications modernes nécessitent une technologie de mise en cache efficace et fiable pour améliorer les performances et gérer de grandes quantités de données. En raison de la popularité de PHP et de sa nature open source, la bibliothèque de mise en cache PHP est devenue un outil essentiel dans la communauté du développement Web. Memcached est un système de mise en cache mémoire haute vitesse open source largement utilisé qui peut gérer des millions de requêtes de cache connectées simultanément et peut être utilisé dans de nombreux types d'applications différents, tels que les réseaux sociaux, en ligne.

Comment optimiser l'utilisation du processeur des applications PHP à l'aide de la technologie de mise en cache Memcached ? Comment optimiser l'utilisation du processeur des applications PHP à l'aide de la technologie de mise en cache Memcached ? Jun 21, 2023 pm 05:07 PM

Avec le développement d'Internet, les applications PHP sont devenues de plus en plus courantes dans le domaine des applications Internet. Cependant, un accès simultané élevé par les applications PHP peut entraîner une utilisation élevée du processeur sur le serveur, affectant ainsi les performances de l'application. Afin d'optimiser les performances des applications PHP, la technologie de mise en cache Memcached est devenue un bon choix. Cet article explique comment utiliser la technologie de mise en cache Memcached pour optimiser l'utilisation du processeur des applications PHP. Introduction à la technologie de mise en cache Memcached Memcached est un

Sauvegarde et récupération de bases de données PHP et Memcached Sauvegarde et récupération de bases de données PHP et Memcached May 15, 2023 pm 09:12 PM

Avec le développement rapide d'Internet, la sauvegarde et la restauration de bases de données MySQL à grande échelle sont devenues l'une des compétences essentielles des grandes entreprises et des sites Web. Avec l'application généralisée de Memcached, la manière de sauvegarder et de restaurer Memcached est également devenue un problème important. En tant que l'un des principaux langages de développement Web, PHP présente des avantages et des compétences uniques dans la gestion de la sauvegarde et de la récupération de MySQL et Memcached. Cet article présentera en détail la méthode d'implémentation du traitement PHP de la sauvegarde et de la récupération MySQL et Memcached.

Gestion du cache avec PHP et Memcached Gestion du cache avec PHP et Memcached May 23, 2023 pm 02:21 PM

Avec l'augmentation continue des applications réseau et l'expansion continue du volume de données, l'efficacité de la lecture et de l'écriture des données est devenue l'un des facteurs importants affectant les performances des applications. L’application de la technologie de mise en cache peut bien résoudre ce problème. Dans les applications PHP, Memcached est le serveur de cache le plus couramment utilisé. Memcached est un système de mise en cache d'objets de mémoire distribuée hautes performances qui peut stocker les données couramment utilisées en mémoire et améliorer l'efficacité de la récupération des données. Cet article expliquera comment utiliser PHP et Memcached pour la gestion du cache, et comment optimiser

Utilisez la technologie de mise en cache Memcached pour optimiser la lecture audio et vidéo en PHP Utilisez la technologie de mise en cache Memcached pour optimiser la lecture audio et vidéo en PHP May 17, 2023 pm 04:01 PM

Avec le développement continu de la technologie Internet, les ressources audio et vidéo sont devenues une forme de contenu très importante sur Internet, et PHP, en tant que l'un des langages les plus utilisés dans le développement de réseaux, est également constamment utilisé dans le domaine de la vidéo. et la lecture audio. Cependant, avec le nombre croissant d'utilisateurs de sites Web audio et vidéo, de nombreux sites Web ont découvert un problème : dans des conditions de concurrence élevée, la vitesse de traitement de l'audio et de la vidéo par PHP ralentit considérablement, ce qui entraîne des problèmes tels qu'une incapacité à lire à temps ou une lecture bloquée. . Pour résoudre ce problème, la technologie de mise en cache Memcached doit

Surveillance des performances PHP et Memcached Surveillance des performances PHP et Memcached May 15, 2023 pm 09:51 PM

Avec le développement rapide des applications Internet modernes, l’expérience utilisateur est cruciale pour le succès d’une application. Comment garantir des performances élevées et une haute disponibilité des applications est devenu l'un des problèmes importants que les développeurs doivent résoudre. En tant que langage de programmation largement utilisé, la surveillance et l'optimisation des performances de PHP sont également très importantes. Memcached est un système de mise en cache d'objets à mémoire distribuée hautes performances qui peut aider les applications à améliorer leurs performances et leur évolutivité. Cet article explique comment utiliser PHP et Memcached pour implémenter la surveillance des performances.

Comment utiliser Memcached avec CakePHP ? Comment utiliser Memcached avec CakePHP ? Jun 04, 2023 am 08:14 AM

Avec la croissance rapide des applications modernes, la mise en cache est devenue un élément essentiel pour de nombreux développeurs. La mise en cache peut améliorer considérablement les performances des applications et réduire la charge du serveur. Dans CakePHP, une façon d’implémenter la mise en cache consiste à utiliser Memcached. Memcached est un système de mise en cache distribué basé sur la mémoire. Il stocke les données en mémoire et peut lire et écrire des données rapidement. Dans un environnement multi-serveur, Memcached peut stocker les données de manière distribuée et les partager sur le réseau. Non seulement peut

See all articles