Memcached

NoSQL

NoSQL 是对Not Only SQL,非传统关系型数据库的统称

分类

Key-value Store k/v数据库:性能好 O(1) , 如: redis、memcached

Document Store 文档数据库:mongodb、CouchDB

Column Store 列存数据库,Column-Oriented DB:HBase、Cassandra,大数据领域应用广泛

Graph DB 图数据库:Neo4j

Time Series 时序数据库:InfluxDB、Prometheus

Memcached

在这里插入图片描述

Memcached是一个自由开源的,高性能的,分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。 Memcached基于一个存储键/值对的hashmap。其守护进程(daemon)是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。

Memcached是基于内存的缓存系统,因此一旦服务器宕机或重启,缓存数据将丢失。不支持缓存持久化。

Memcached和Redis对比

比较项目RedisMemcached
支持的数据结构哈希、列表、集合、有序集合纯key-value
持久化支持
高可用支持redis支持集群功能,可以实现主动复制,读写分离。
官方也提供了sentinel集群管理工具,能够实现主从服务监控,故障自动转移,这一切,对于客户端都是透明的,无需程序改动,也无需人工个入
需要二次开发
存储value容量最大512M最大1M
内存分配临时申请空间,可能导致碎片预分配内存池的方式管理内存,省去分配内存时间
虚拟内存使用有自己的VM机制,理论上能够储存比物理内存更多的数据,当数据超量时,会引发swap,把冷数据刷到磁盘上所有数据存储在物理内存里
网络模型非阻塞IO复用模型,提供一些非KV存储之外的排序,聚合功能,在执行这些功能时,复杂的CPU计算,会阻塞整个IO调度非阻塞IO复用模型
水平拓展的支持redis cluster 可以横向拓展暂无
多线程redis6.0 之前只支持单线程Memcached支持多线程,CPU利用方面Memcache优于redis
过期策略有专门线程,清除缓存数据懒淘汰机制:每次往缓存放入数据的时候,都会存一个时间,在读取的时候要和设置的时间做TTL比较来判断是否过期
单机QPS约10W约60W
源代码可读性代码清爽简洁不清爽
使用场景负载数据结构,有持久化,高可用需求,value存储内容大纯kv,数据量非常大,并发量非常大的业务

工作机制

内存分配机制

应用程序运行需要使用内存存储数据,但对于一个缓存系统来说,申请内存、释放内存将十分频繁,非常容易导致大量内存碎片,最后导致无连续可用内存可用,本该能存储的数据量却无法存储。

Memcached采用了Slab Allocator机制来分配、管理内存。

  • Page:分配给Slab的内存空间,默认为1MB,分配后就得到一个Slab。Slab分配之后内存按照固定字节大小等分成chunk。
  • Chunk:用于缓存记录k/v值的内存空间。Memcached会根据数据大小选择存到哪一个chunk中,假设chunk有128bytes、64bytes等多种,数据只有100bytes存储在128bytes中,存在少许浪费。
  • Chunk最大就是Page的大小,即一个Page中就一个ChunkSlab Class:Slab按照Chunk的大小分组,就组成不同的Slab Class, 第一个Chunk大小为 96B的Slab为Class1,Chunk 120B为Class 2,如果有100bytes要存,那么Memcached会选择下图中Slab Class 2 存储,因为它是120bytes的Chunk。Slab之间的差异可以使用Growth Factor 控制,默认1.25

在这里插入图片描述

查看Slab Class

[root@wenzi memcached-1.6.20]#memcached -u memcached -d -f 2 -vv
slab class   1: chunk size        96 perslab   10922
slab class   2: chunk size       192 perslab    5461
slab class   3: chunk size       384 perslab    2730
slab class   4: chunk size       768 perslab    1365
slab class   5: chunk size      1536 perslab     682
slab class   6: chunk size      3072 perslab     341
slab class   7: chunk size      6144 perslab     170
slab class   8: chunk size     12288 perslab      85
slab class   9: chunk size     24576 perslab      42
slab class  10: chunk size     49152 perslab      21
slab class  11: chunk size     98304 perslab      10
slab class  12: chunk size    196608 perslab       5
slab class  13: chunk size    524288 perslab       2
<22 server listening (auto-negotiate)
<23 server listening (auto-negotiate)

懒过期 Lazy Expiration

memcached不会监视数据是否过期,而是在取数据时才看是否过期,如果过期,把数据有效期限标识为0,并不清除该数据。以后可以覆盖该位置存储其它数据

LRU 最近最少使用

当内存不足时,memcached会使用LRU(Least Recently Used)机制来查找可用空间,分配给新记录使用

集群

Memcached集群,称为基于客户端 的分布式集群,即由客户端实现集群功能,即Memcached本身不支持集群。

Memcached集群内部并不互相通信,一切都需要客户端连接到Memcached服务器后自行组织这些节点,并决定数据存储的节点

安装

官方文档:http://memcached.org/downloads

[root@wenzi ~]#apt update && apt -y install gcc make libevent-dev
[root@wenzi ~]#tar -xf memcached-1.6.20.tar.gz
[root@wenzi ~]#cd memcached-1.6.20/
[root@wenzi memcached-1.6.20]#./configure --prefix=/apps/memcached
[root@wenzi memcached-1.6.20]#make && make install
[root@wenzi memcached-1.6.20]#tree /apps/memcached/
/apps/memcached/
├── bin
│   └── memcached
├── include
│   └── memcached
│       ├── protocol_binary.h
│       └── xxhash.h
└── share
    └── man
        └── man1
            └── memcached.1

6 directories, 4 files
[root@wenzi memcached-1.6.20]#ln -s /apps/memcached/bin/memcached /usr/local/bin/
#不允许以root身份运行
[root@wenzi memcached-1.6.20]#memcached
can't run as root without the -u switch
#创建Memcached用户
[root@wenzi memcached-1.6.20]#useradd -r -s /sbin/nologin memcached
[root@wenzi memcached-1.6.20]#memcached -u memcached -d -f 2 -vv
slab class   1: chunk size        96 perslab   10922
slab class   2: chunk size       192 perslab    5461
slab class   3: chunk size       384 perslab    2730
slab class   4: chunk size       768 perslab    1365
slab class   5: chunk size      1536 perslab     682
slab class   6: chunk size      3072 perslab     341
slab class   7: chunk size      6144 perslab     170
slab class   8: chunk size     12288 perslab      85
slab class   9: chunk size     24576 perslab      42
slab class  10: chunk size     49152 perslab      21
slab class  11: chunk size     98304 perslab      10
slab class  12: chunk size    196608 perslab       5
slab class  13: chunk size    524288 perslab       2
<22 server listening (auto-negotiate)
<23 server listening (auto-negotiate)

[root@wenzi memcached-1.6.20]#ss -tnlp | grep memcached
LISTEN 0      1024         0.0.0.0:11211      0.0.0.0:*    users:(("memcached",pid=3929,fd=22))
LISTEN 0      1024            [::]:11211         [::]:*    users:(("memcached",pid=3929,fd=23))

#准备service文件
[root@wenzi memcached-1.6.20]#vim /lib/systemd/system/memcached.service
[Unit]
Description=memcached daemon
After=network.target

[Service]
ExecStart=/usr/local/bin/memcached -u memcached -m 100 -c 10240

[Install]
WantedBy=multi-user.target

[root@wenzi memcached-1.6.20]#systemctl daemon-reload

启动说明

通过/etc/sysconfig/memcached修改memcached 运行参数

-u username memcached运行的用户身份,必须普通用户
-p 绑定的端口,默认11211
-m num 最大内存,单位MB,默认64MB
-c num 最大连接数,缺省1024
-d 守护进程方式运行
-f 增长因子Growth Factor,默认1.25
-v 详细信息,-vv能看到详细信息
-M 使用内存直到耗尽,不许LRU
-U 设置UDP监听端口,0表示禁用UDP

使用Memcached

与memcached通信的不同语言的连接器。libmemcached提供了C库和命令行工具

[root@wenzi ~]#apt -y install libmemcached-tools
#ping测Memcached是否正在运行
[root@wenzi ~]#/usr/bin/memcping --servers=192.168.28.60
#显示 Memcached 服务器的统计信息,如命中率、内存使用情况等
[root@wenzi ~]#memcstat --servers=192.168.28.60
Server: 192.168.28.60 (11211)
         pid: 18797
         uptime: 2018
         time: 1709363976
         version: 1.6.20
         libevent: 2.1.12-stable
         pointer_size: 64
         rusage_user: 0.136119
         rusage_system: 0.100906
         max_connections: 10240
         curr_connections: 2
         total_connections: 4
         rejected_connections: 0
         connection_structures: 3
         response_obj_oom: 0
         response_obj_count: 1
         response_obj_bytes: 32768
         read_buf_count: 4
         read_buf_bytes: 65536
         read_buf_bytes_free: 16384
         read_buf_oom: 0
         reserved_fds: 20
         cmd_get: 0
         cmd_set: 0
         cmd_flush: 0
         cmd_touch: 0
         cmd_meta: 0
         get_hits: 0
         get_misses: 0
         get_expired: 0
         get_flushed: 0
         delete_misses: 0
         delete_hits: 0
         incr_misses: 0
         incr_hits: 0
         decr_misses: 0
         decr_hits: 0
         cas_misses: 0
         cas_hits: 0
         cas_badval: 0
         touch_hits: 0
         touch_misses: 0
         store_too_large: 0
         store_no_memory: 0
         auth_cmds: 0
         auth_errors: 0
         bytes_read: 32
         bytes_written: 32
         limit_maxbytes: 104857600
         accepting_conns: 1
         listen_disabled_num: 0
         time_in_listen_disabled_us: 0
         threads: 4
         conn_yields: 0
         hash_power_level: 16
         hash_bytes: 524288
         hash_is_expanding: 0
         slab_reassign_rescues: 0
         slab_reassign_chunk_rescues: 0
         slab_reassign_evictions_nomem: 0
         slab_reassign_inline_reclaim: 0
         slab_reassign_busy_items: 0
         slab_reassign_busy_deletes: 0
         slab_reassign_running: 0
         slabs_moved: 0
         lru_crawler_running: 0
         lru_crawler_starts: 8
         lru_maintainer_juggles: 2066
         malloc_fails: 0
         log_worker_dropped: 0
         log_worker_written: 0
         log_watcher_skipped: 0
         log_watcher_sent: 0
         log_watchers: 0
         unexpected_napi_ids: 0
         round_robin_fallback: 0
         bytes: 0
         curr_items: 0
         total_items: 0
         slab_global_page_pool: 0
         expired_unfetched: 0
         evicted_unfetched: 0
         evicted_active: 0
         evictions: 0
         reclaimed: 0
         crawler_reclaimed: 0
         crawler_items_checked: 0
         lrutail_reflocked: 0
         moves_to_cold: 0
         moves_to_warm: 0
         moves_within_lru: 0
         direct_reclaims: 0
         lru_bumps_dropped: 0

五种基本 memcached 命令执行最简单的操作:set、add、replace、get、delete

set、add、replace用于操作存储在 memcached 中的键值对的标准修改命令
command <key> <flags> <expiration time> <bytes>
<value>
参数说明:
command set/add/replace
key     	key 用于查找缓存值
flags     	可以包括键值对的整型参数,客户机使用它存储关于键值对的额外信息
expiration time     在缓存中保存键值对的时间长度(以秒为单位,0 表示永远)
bytes     	在缓存中存储的字节数
value     	存储的值(始终位于第二行)
#增加key,过期时间为秒,bytes为存储数据的字节数
add key flags exptime bytes

[root@wenzi ~]#telnet localhost 11211
stats
STAT pid 18797
STAT uptime 2792
STAT time 1709364750
STAT version 1.6.20
STAT libevent 2.1.12-stable
STAT pointer_size 64
STAT rusage_user 0.167935
STAT rusage_system 0.167935
STAT max_connections 10240
STAT curr_connections 2
STAT total_connections 6
STAT rejected_connections 0
STAT connection_structures 3
STAT response_obj_oom 0
STAT response_obj_count 1
STAT response_obj_bytes 65536
STAT read_buf_count 8
STAT read_buf_bytes 131072
STAT read_buf_bytes_free 49152
STAT read_buf_oom 0
STAT reserved_fds 20
STAT cmd_get 0
STAT cmd_set 0
STAT cmd_flush 0
STAT cmd_touch 0
STAT cmd_meta 0
STAT get_hits 0
STAT get_misses 0
STAT get_expired 0
STAT get_flushed 0
STAT delete_misses 0
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT store_too_large 0
STAT store_no_memory 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 59
STAT bytes_written 2265
STAT limit_maxbytes 104857600
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT time_in_listen_disabled_us 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT slab_reassign_rescues 0
STAT slab_reassign_chunk_rescues 0
STAT slab_reassign_evictions_nomem 0
STAT slab_reassign_inline_reclaim 0
STAT slab_reassign_busy_items 0
STAT slab_reassign_busy_deletes 0
STAT slab_reassign_running 0
STAT slabs_moved 0
STAT lru_crawler_running 0
STAT lru_crawler_starts 10
STAT lru_maintainer_juggles 2840
STAT malloc_fails 0
STAT log_worker_dropped 0
STAT log_worker_written 0
STAT log_watcher_skipped 0
STAT log_watcher_sent 0
STAT log_watchers 0
STAT unexpected_napi_ids 0
STAT round_robin_fallback 0
STAT bytes 0
STAT curr_items 0
STAT total_items 0
STAT slab_global_page_pool 0
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT evicted_active 0
STAT evictions 0
STAT reclaimed 0
STAT crawler_reclaimed 0
STAT crawler_items_checked 0
STAT lrutail_reflocked 0
STAT moves_to_cold 0
STAT moves_to_warm 0
STAT moves_within_lru 0
STAT direct_reclaims 0
STAT lru_bumps_dropped 0
END

[root@wenzi ~]#telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
add mykey 1 60 4	#增加键名为mykey、描述为1、有效期60s、字节数4的值
test				#mykey的值为test
STORED				#已储存
get mykey			#查询键名mykey的值
VALUE mykey 1 4
test
END
set mykey 1 60 2	#修改
cs
STORED
get mykey
VALUE mykey 1 2
cs
END
delete mykey		#删除
DELETED
get mykey
END
flush_all			#清空
OK
get mykey
END
quit
Connection closed by foreign host.

#非交互式取信息
[root@wenzi ~]#echo -e "stats\nquit" | nc 192.168.28.60 11211 | awk '/pid/{print $NF}'
  • 12
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值