高性能内存对象缓存

MemCached

一、概述

  • 定义:Memcached是一个内存中的键值对存储系统,支持任意存储类型的数据,如字符串、对象等。
  • 架构:Memcached采用C/S(客户端/服务器)架构,需要安装Memcached服务端与Memcached API客户端。
  • 特点:数据存储在内存中,通过维护一张巨大的Hash表来支持高效的读写操作。

二、数据存储与过期方式

  • 数据存储方式:Memcached采用Slab Allocation机制来分配和管理内存。Slab是memcached分配的基本单位,每个slab对应多张Page(默认大小是1MB),每张Page会被划分为多个chunk,chunk中保存了item结构体、一对key和value。
  • 数据过期方式
    • LRU(Least Recently Used):当数据空间不足时,会根据LRU算法淘汰最近最少使用的记录。
    • Laxzy Expiration(惰性过期):在get操作时检查记录时间,从而确定记录是否已过期。

三、工作原理

  • 写入流程
    1. 应用程序输入需要写缓存的数据。
    2. API将Key输入路由算法模块,路由算法根据Key和Memcached集群服务器列表得到一台服务器编号。
    3. 由服务器编号得到Memcached服务节点的IP地址和端口号。
    4. API调用通信模块和指定编号的服务器通信,将数据写入该服务器,完成一次分布式缓存的写操作。
  • 读取流程
    1. 应用程序输入需要读取的Key。
    2. 路由算法根据Key和Memcached集群服务器列表确定存储该数据的服务器。
    3. API调用通信模块从指定服务器读取数据。
    4. 如果缓存命中,则直接返回数据;如果缓存未命中,则先从数据库中查询数据,再将数据缓存到Memcached中。

四、分布式部署

  • 依赖:Memcached的分布式部署主要依赖于Memcached的客户端来实现。
  • 路由算法
    • 求余数Hash算法:适合大多数据需求,但不适合动态变化的环境。
    • 一致性Hash算法:适合在动态变化的环境中使用,通过hash算法将key和机器映射到环中,按顺时针方向将对象存储到离自己最近的机器中。

五、优化与注意事项

  • 安装与配置:Memcached的安装依赖于Libevent库,需要先安装Libevent。安装完成后,可以通过配置文件或命令行参数来优化Memcached的性能,如设置最大内存、最大连接数等。
  • 数据一致性:由于Memcached是内存缓存,因此不具备数据持久性。当Memcached服务器重启或发生故障时,缓存的数据会丢失。因此,在使用Memcached时,需要考虑数据备份和恢复策略。
  • 监控与维护:定期对Memcached进行监控和维护,包括查看缓存命中率、内存使用情况、连接数等指标,以确保Memcached的稳定运行和高效性能。

六、应用场景

Memcached适用于需要频繁访问数据的场景,如动态Web应用、社交网络、电子商务等。通过减少数据库加载,Memcached可以显著提高这些应用的访问速度和性能。

综上所述,Memcached是一款功能强大、性能优异的高性能内存对象缓存系统。通过合理的配置和优化,可以充分发挥其优势,为Web应用提供快速、高效的数据访问服务。

案例

单memcached节点缓存系统

cpp 复制代码
//设置节点的主机名
主机:192.168.10.101
[root@localhost ~]# hostnamectl set-hostname Memcache1
[root@localhost ~]# bash

主机:192.168.10.103
[root@localhost ~]# hostnamectl set-hostname Memcached-API
[root@localhost ~]# bash
安装 Memcached 服务器
cpp 复制代码
//安装 Libevent
[root@memcache1 ~]# systemctl stop firewalld
[root@memcache1 ~]# yum -y install gcc*
[root@memcache1 ~]# tar zxvf libevent-2.1.8-stable.tar.gz 
[root@memcache1 ~]# cd libevent-2.1.8-stable
[root@memcache1 libevent-2.1.8-stable]# ./configure --prefix=/usr/local/libevent
[root@memcache1 libevent-2.1.8-stable]# make && make install


//安装 Memcached
[root@memcache1 ~]# tar zxvf memcached-1.5.1.tar.gz 
[root@memcache1 ~]# cd memcached-1.5.1
[root@memcache1 memcached-1.5.1]# ./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent

[root@memcache1 memcached-1.5.1]# make && make install

//设置 Memcached 服务脚本
[root@memcache1 ~]# vim /usr/local/memcached/memcached_service.sh
#!/bin/bash 
CMD="/usr/local/memcached/bin/memcached" 
start(){ 
  $CMD -d -m 128 -u root
}
stop(){ 
  killall memcached;
}

ACTION=$1
  case $ACTION in
  'start')
     start;;
  'stop')
     stop;;
'restart')
     stop
     sleep 2
     start;;
*) 
     echo 'Usage:{start|stop|restart}' 
esac 

[root@memcache1 ~]# yum -y install psmisc
备注:
psmisc提供了killall命令

[root@memcache1 ~]# chmod 755 /usr/local/memcached/memcached_service.sh
[root@memcache1 ~]# /usr/local/memcached/memcached_service.sh start
[root@memcache1 ~]# netstat -anpt | grep memcached
tcp        0      0 0.0.0.0:11211           0.0.0.0:*               LISTEN      20564/memcached     
tcp6       0      0 :::11211                :::*                   LISTEN      20564/memcached  
Memcached API 客户端
cpp 复制代码
//设置好阿里yum源,配置环境

yum -y install httpd mariadb mariadb-server php php-devel php-mysql
systemctl start mariadb
mysqladmin -u root password 'pwd123'
systemctl start httpd

cat <<EOF>/var/www/html/test1.php
<?php
phpinfo();
?>
EOF

//编译安装 Libmemcached
[root@memcached-api ~]# systemctl stop firewalld
[root@memcached-api ~]# setenforce 0

[root@memcached-api ~]# yum -y install gcc*
[root@memcached-api ~]# tar zxvf libmemcached-1.0.18.tar.gz 
[root@memcached-api ~]# cd libmemcached-1.0.18

[root@memcached-api libmemcached-1.0.18]# ./configure \
--prefix=/usr/local/libmemcached \
--with-memcached=/usr/local/memcached

[root@memcached-api libmemcached-1.0.18]# make && make install


//编译安装 Memcached 扩展
[root@memcached-api ~]# yum -y install zlib zlib-devel
[root@memcached-api ~]# tar -xzvf memcached-2.2.0.tgz 
[root@memcached-api ~]# cd memcached-2.2.0/
[root@memcached-api memcached-2.2.0]# /usr/bin/phpize
[root@memcached-api memcached-2.2.0]# ./configure --with-php-config=/usr/bin/php-config --with-libmemcached-dir=/usr/local/libmemcached --disable-memcached-sasl --with-zlib-dir

//配置 PHP 添加 Memcached 组件
[root@memcache2 ~]# vim /etc/php.ini
在第二行添加extension=memcached.so 

通过 PHPinfo 查看是否已经添加 Memcached 扩展模块

测试 Memcached-API 功能

cpp 复制代码
[root@memcached-api ~]# vim /var/www/hrml/test2.php

<?php 
$memcache = new Memcached(); 
$memcache->addServer('192.168.10.101', 11211); 
$memcache->set('key', 'Memcache test successful!', 0, 60); 
$result = $memcache->get('key'); 
unset($memcache); 
echo $result; 
?> 

Memcached主主复制架构部署

cpp 复制代码
//安装 Libevent

[root@memcache1 ~]# systemctl stop firewalld
[root@memcache1 ~]# setenforce 0
 
[root@memcache1 ~]# yum -y install gcc* psmisc
[root@memcache1 ~]# tar zxvf libevent-2.1.8-stable.tar.gz 
[root@memcache1 ~]# cd libevent-2.1.8-stable
[root@memcache1 libevent-2.1.8-stable]# ./configure --prefix=/usr/local/libevent
[root@memcache1 libevent-2.1.8-stable]# make && make install

//安装memcached-1.2.8-repcached

[root@memcache1 ~]# tar zxvf memcached-1.2.8-repcached-2.2.tar.gz 
[root@memcache1 ~]# cd memcached-1.2.8-repcached-2.2
[root@Memcached1 memcached-1.2.8-repcached-2.2]# ./configure \
--prefix=/usr/local/memcached_replication \
--enable-replication \
--with-libevent=/usr/local/libevent
 
[root@memcache1 memcached-1.2.8-repcached-2.2]# vim memcached.c
//找到如下两行删除(在55行--60行):
//if defined(__FreeBSD__) || defined(__APPLE__)
//endif
 
[root@memcache1 memcached-1.2.8-repcached-2.2]# make && make install

//启动memcached1服务
[root@memcache1 ~]# ln -s /usr/local/libevent/lib/libevent-2.1.so.6 /usr/lib64/
[root@Memcached1 ~]# /usr/local/memcached_replication/bin/memcached -d -u root -m 128 -x 192.168.10.102
//memcached2启动
[root@memcache1 ~]# ln -s /usr/local/libevent/lib/libevent-2.1.so.6 /usr/lib64/
[root@Memcached1 ~]# /usr/local/memcached_replication/bin/memcached -d -u root -m 128 -x 192.168.10.101

//使用 telnet 进行简单验证复制功能

Memcached 主主复制+Keepalived高可用架构

在上面案例的基础上添加keepalived

配置主 keepalived

cpp 复制代码
[root@memcache1 ~]# vim /etc/keepalived/keepalived.conf 
! Configuration File for keepalived
global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_01
   vrrp_skip_check_adv_addr
   #vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}
vrrp_script check_down {     //定义要执行的脚本
script "/etc/keepalived/memcached.sh"		//脚本路径和名称
interval 1		//间隔1秒执行一次
}
vrrp_instance VI_1 {
    state BACKUP      //master角色不能设置nopreempt,所以此处要设置为BACKUP
    interface ens33
    virtual_router_id 51
    priority 100    //从主机的优先级要小于此数字
advert_int 1
nopreempt		//添加,此语句关闭了抢占功能,从主机不需要
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.10.100
}
track_script {		//调用前面的脚本
 check_down
}
}

配置从keepalived,只需要在主keepalived的配置文件的基础上进行修改即可

cpp 复制代码
[root@memcache1 ~]# vim /etc/keepalived/keepalived.conf 
! Configuration File for keepalived
global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_02                    //route_id不能相同
   vrrp_skip_check_adv_addr
   #vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}
vrrp_script check_down { 
script "/etc/keepalived/memcached.sh"
interval 1	
}
vrrp_instance VI_1 {
    state BACKUP 
    interface ens33
    virtual_router_id 51
    priority 99                //从主机的优先级要小于主机
advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.10.100
}
track_script {	
 check_down
}
}

memcached.sh脚本内容

cpp 复制代码
[root@memcached2 keepalived]# vim /etc/keepalived/memcached.sh
 
#!/bin/bash
#
if [ $(ps -C memcached --no-header | wc -l) -eq 0 ]; then
       systemctl stop keepalived
fi

[root@memcached2 keepalived]# chmod +x /etc/keepalived/memcached.sh

关闭memcached后,该主机的keepalived也会被脚本关闭,于是VIP就漂移到了另一台主机,待此主机修好后,把memcached和keepalived开启,由于设置了不抢占,VIP不会抢占回来,但是把第二台主机的memcached关闭后,第二台主机的keepalived也会关闭,于是VIP就漂移回了第一台主机。完成故障的转移。

相关推荐
客院载论11 小时前
Redis学习——数据不一致怎么办?更新缓存失败了又怎么办?
redis·学习·缓存
Coder.Ren11 小时前
【白话Redis】缓存雪崩、穿透、击穿、失效和热点缓存重建
数据库·redis·缓存
黑金IT12 小时前
智能负载均衡:分布式缓存的高效能解决方案
分布式·缓存·负载均衡
bxnms.16 小时前
Redis之pipeline与事务
数据库·redis·缓存
小扳17 小时前
Redis 篇-深入了解使用 Redis 中的 GEO 数据结构实现查询附近店铺、BitMap 实现签到功能、HyperLogLog 实现 UV 流量统计
java·数据库·redis·后端·缓存
ezreal_pan17 小时前
redis有序集合写入和求交集的速度
数据库·redis·缓存·zset
正经人_____19 小时前
0x07 Nginx越界读取缓存漏洞 CVE-2017-7529 复现
缓存
叫我DPT19 小时前
Django REST framework 实现缓存机制以优化性能
python·缓存·django·drf
你可以叫我仔哥呀20 小时前
学习笔记缓存篇(一)
笔记·学习·缓存
M-bao20 小时前
Redis在单线程下删除大Key会发生什么?怎么删除大Key?
redis·缓存