NoSQL是对 Not Only SQL、非传统关系型数据库的统称。
NoSQL一词诞生于1998年,2009年这个词汇被再次提出指非关系型、分布式、不提供ACID的数据库设计模式。
随着互联网时代的到来,数据爆发式增长,数据库技术发展日新月异,要适应新的业务需求。
而随着移动互联网、物联网的到来,大数据的技术中NoSQL也同样重要。
数据库排名:https://db-engines.com/en/ranking
NoSQL 分类
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 只支持能序列化的数据类型,不支持持久化,基于Key-Value的内存缓存系统
memcached 虽然没有像redis所具备的数据持久化功能,比如RDB和AOF都没有,但是可以通过做集群同步的方式,让各memcached服务器的数据进行同步,从而实现数据的一致性,即保证各memcached的数据是一样的,即使有任何一台 memcached 发生故障,只要集群中有一台 memcached 可用就不会出现数据丢失,当其他memcached 重新加入到集群的时候,可以自动从有数据的memcached 当中自动获取数据并提供服务
Memcached 借助了操作系统的 libevent 工具做高效的读写。libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能封装成统一的接口。即使对服务器的连接数增加,也能发挥高性能。memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能
Memcached 支持最大的内存存储对象为1M,超过1M的数据可以使用客户端压缩或拆分报包放到多个key中,比较大的数据在进行读取的时候需要消耗的时间比较长,memcached 最适合保存用户的session实现session共享
Memcached存储数据时, Memcached会去申请1MB的内存, 把该块内存称为一个slab, 也称为一个page
Memcached 支持多种开发语言,包括:JAVA,C,Python,PHP,C#,Ruby,Perl等
Memcached 官网:http://memcached.org/
| 比较类别 | Redis | memcached |
|---|---|---|
| 支持的数据结构 | 哈希、列表、集合、有序集合 | 纯kev-value |
| 持久化支持 | 有 | 无 |
| 高可用支持 | redis支持集群功能,可以实现主动复制,读写分离官方也提供了sentinel集群管理工具,能够实现主从服务监控,故障自动转移,这一切,对于客户端都是透明的,无需程序改动,也无需人工介入 | 需要二次开发 |
| 存储value容量 | 最大512M | 最大1M |
| 内存分配 | 临时申请空间,可能导致碎片 | 预分配内存池的方式管理内存,能够省去内存分配时间 |
| 虚拟内存使用 | 有自己的VM机制,理论上能够存储比物理内存更多的数据,当数据超量时,会引发swap,把冷数据刷到磁盘上 | 所有的数据存储在物理内存里 |
| 网络类型 | 非阻塞IO复用模型,提供一些非KV存储之外的排序聚合功能,在执行这些功能时,复杂的CPU计算,会阻塞整个IO调度 | 非阻塞IO复用模型 |
| 水平扩展支持 | redis cluster 可以横向扩展 | 暂无 |
| 多线程 | Redis6.0之前是只支持单线程 | Memcached支持多线程,CPU利用方面Memcache优于redis |
| 单机QPS | 约10W | 约60W |
| 源代码可读性 | 代码清爽简洁 | 可能是考虑了太多的扩展性,多系统的兼容性,代码不清爽 |
| 适用场景 | 复杂数据结构、有持久化、高可用需求、value存储内容较大 | 纯KV,数据量非常大,并发量非常大的业务 |
应用程序运行需要使用内存存储数据,但对于一个缓存系统来说,申请内存、释放内存将十分频繁,非常容易导致大量内存碎片,最后导致无连续可用内存可用。
Memcached采用了Slab Allocator机制来分配、管理内存。

范例:查看Slab Class
- #-f, --slab-growth-factor=<num> chunk size growth factor (default: 1.25)
- [root@centos7 ~]#memcached -u memcached -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
- <27 server listening (auto-negotiate)
- <28 server listening (auto-negotiate)
memcached不会监视数据是否过期,而是在取数据时才看是否过期,如果过期,把数据有效期限标识为0,并不清除该数据。以后可以覆盖该位置存储其它数据。
当内存不足时,memcached会使用LRU(Least Recently Used)机制来查找可用空间,分配给新记录使用
Memcached集群,称为基于客户端的分布式集群,即由客户端实现集群功能,即Memcached本身不支持集群
Memcached集群内部并不互相通信,一切都需要客户端连接到Memcached服务器后自行组织这些节点,并决定数据存储的节点。
官方安装说明
Install · memcached/memcached Wiki · GitHub
yum install -y memcached
- [root@localhost ~]#yum info memcached
- 已加载插件:fastestmirror, langpacks
- Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast
- Determining fastest mirrors
- * base: mirrors.nju.edu.cn
- * extras: mirrors.nju.edu.cn
- * updates: mirrors.nju.edu.cn
- 可安装的软件包
- 名称 :memcached
- 架构 :x86_64
- 版本 :1.4.15
- 发布 :10.el7_3.1
- 大小 :85 k
- 源 :base/7/x86_64
- 简介 : High Performance, Distributed Memory Object Cache
- 网址 :http://www.memcached.org/
- 协议 : BSD
- 描述 : memcached is a high-performance, distributed memory object caching
- : system, generic in nature, but intended for use in speeding up dynamic
- : web applications by alleviating database load.
配置文件:
- [root@localhost ~]#vim /etc/sysconfig/memcached
- PORT="11211" #监听端口
- USER="memcached" #启动用户
- MAXCONN="1024" #最大连接数
- CACHESIZE="64" #最大使用内存
- OPTIONS="" #其他选项
-
-
- OPTIONS="" 表示该行用于定义启动 Memcached 时附加的命令行选项。当 OPTIONS 变量为空字符串时,
- 意味着没有指定任何额外的启动参数。
-
-
- Memcached 在启动时可以通过 -o 参数或者直接在配置文件中指定一系列可选配置项,这些配置项可以包括
- 但不限于:
-
- 绑定监听地址(例如 -l 或 -o listen=127.0.0.1)
- 监听端口(例如 -p 或 -o port=11211)
- 分配给缓存的最大内存大小(例如 -m 或 -o maxmemory=64
- 最大并发连接数(例如 -c 或 -o maxconn=1024)
-
-
- 如:OPTIONS="-l 192.168.1.1 -p 11212 -m 512"
- Memcached 监听 192.168.1.1 地址上的 11212 端口,并分配最多 512MB 内存作为缓存空间。
- yum -y install gcc libevent-devel
- wget http://memcached.org/files/memcached-1.6.6.tar.gz
- tar xvf memcached-1.6.6.tar.gz
- cd memcached-1.6.6/
- ./configure --prefix=/apps/memcached
- make && make install
-
- ln -s /apps/memcached/bin/memcached /usr/bin
-
- #准备用户
- useradd -r -s /sbin/nologin memcached
-
-
- cat > /etc/sysconfig/memcached << eof
- PORT="11211"
- USER="memcached"
- MAXCONN="1024"
- CACHESIZE="64"
- OPTIONS=""
- eof
-
-
-
- #准备service文件
- cat > /lib/systemd/system/memcached.service << eof
- [Unit]
- Description=memcached daemon
- Before=httpd.service
- After=network.target
- [Service]
- EnvironmentFile=/etc/sysconfig/memcached
- ExecStart=/apps/memcached/bin/memcached -p \${PORT} -u \${USER} -m \${CACHESIZE} -c \${MAXCONN} \$OPTIONS
- [Install]
- WantedBy=multi-user.target
- eof
-
-
- systemctl daemon-reload
- systemctl enable --now memcached.service
- memcached --version
-
-
- #在多行重定向或多行字符串中,\ 在变量名前面用来确保变量名跨越多行仍然能够被正确解析。
增长因子的改变
- #默认前台执行
- [root@centos7 ~]#memcached -u memcached -m 1024 -c 65536 -f 2 -vv
-
- #以台方式执行
- [root@centos7 ~]#memcached -u memcached -m 1024 -c 65536 -d
修改memcached 运行参数,可以使用下面的选项修改/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通信的不同语言的连接器。libmemcached提供了C库和命令行工具。
范例:
#安装工具包
yum install libmemcached -y
memping 检测连接服务器
- [root@node2 ~]#memping --help
- memping v1.0
-
- Ping a server to see if it is alive
-
- Current options. A '=' means the option takes a value.
-
- --version
- Display the version of the application and then exit.
- --help
- Display this message and then exit.
- --quiet
- stderr and stdin will be closed at application startup.
- --verbose
- Give more details on the progression of the application.
- --debug
- Provide output only useful for debugging.
- --servers=
- List which servers you wish to connect to.
- --expire=
- Set the expire option for the object.
- --binary
- Switch to binary protocol.
- --username=
- Username to use for SASL authentication
- --password=
- Password to use for SASL authentication
-
-
-
- #有memcached
- [root@web1 opt]#memping --servers 192.168.80.12
- [root@web1 opt]#echo $?
- 0
-
- #无memcached
- [root@web1 opt]#memping --servers 192.168.80.11
- Failed to ping 192.168.80.11:11211 CONNECTION FAILURE
- [root@web1 opt]#echo $?
- 1
memstat
- [root@web1 opt]#memstat --servers=192.168.80.12
- Server: 192.168.80.12 (11211)
- pid: 60401
- uptime: 1128
- time: 1710390057
- version: 1.6.6
- libevent: 2.0.21-stable
- pointer_size: 64
- rusage_user: 0.078410
- rusage_system: 0.026136
- max_connections: 1024
- curr_connections: 2
- total_connections: 4
- rejected_connections: 0
- connection_structures: 3
- response_obj_bytes: 2336
- response_obj_total: 2
- response_obj_free: 1
- response_obj_oom: 0
- read_buf_bytes: 32768
- 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
- auth_cmds: 0
- auth_errors: 0
- bytes_read: 32
- bytes_written: 30
- limit_maxbytes: 67108864
- 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: 1530
- lru_maintainer_juggles: 1178
- malloc_fails: 0
- log_worker_dropped: 0
- log_worker_written: 0
- log_watcher_skipped: 0
- log_watcher_sent: 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 操作命令
cat /usr/share/doc/memcached/protocol.txt
编译安装不在此处
[root@web1 ~]#find / -name 'protocol.txt'
/usr/lib64/xorg/protocol.txt
/opt/memcached-1.6.6/doc/protocol.txt
五种基本 memcached 命令执行最简单的操作。这些命令和操作包括:
set 重新设置
add 新加一个数据
get 调用
delete 删除数据
- #前三个命令是用于操作存储在 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@wg ~]#telnet 192.168.80.12 11211
- Trying 192.168.80.12...
- Connected to 192.168.80.12.
- Escape character is '^]'.
-
- stats
- #显示服务状态
-
-
- stats items #显示各个 slab 中 item 的数目和存储时长(最后一次访问距离现在的秒数)。
-
-
-
- stats slabs #用于显示各个slab的信息,包括chunk的大小、数目、使用情况等
-
-
-
- quit #退出
例子: 添加数据
- [root@wg ~]#telnet 192.168.80.12 11211
- Trying 192.168.80.12...
- Connected to 192.168.80.12.
- Escape character is '^]'.
-
- add name 1 30 4
- wang
- STORED
-
-
- add 添加
- name 键的名字
- 1 flages标志 描述信息
- 30 超时时间 默认秒 0 代表永久有效
- 4 字节数 数据的大小、
- zhou 具体的值
例子:修改
- set name 1 60 5
- test
-
- 显示CLIENT_ERROR bad data chunk数据格式不正确或者数据内容违反了Memcached的协议规范。
例子:调用数据
- get name
- VALUE name 1 4
- zhou
- END
例子:删除
- get class
- VALUE class 1 4
- asdf
- END
-
- delete class
- DELETED
-
- get class
- END
例子:清空
- flush_all
- OK
- get mykey
- END
-
- quit
Magent是google开发的项目,应用端通过负载均衡服务器连接到magent,然后再由magent代理用户应用请求到memcached处理,底层的memcached为双主结构会自动同步数据,本部署方式存在magent单点问题,因此需要两个magent做高可用。

项目站点:https://code.google.com/archive/p/memagent/
此项目过于陈旧,且不稳定,当前已经废弃

项目站点:repcached - add data replication feature to memcached


在 master上可以通过 -X 选项指定 replication port(默认为11212/tcp),在 slave上通过 -x 指定复制的master并连接,事实上,如果同时指定了 -x/-X, repcached先会尝试连接对端的master,但如果连接失败,它就会用 -X参数来自己 listen(成为master);如果 master坏掉, slave侦测到连接断了,它会自动 listen而成为 master;而如果 slave坏掉,master也会侦测到连接断开,它就会重新 listen等待新的 slave加入。
从这方案的技术实现来看,其实它是一个单 master单 slave的方案,但它的 master/slave都是可读写的,而且可以相互同步,所以从功能上看,也可以认为它是双机 master-master方案
magent已经有很长时间没有更新,因此可以不再使用magent,直接通过负载均衡连接到memcached,仍然有两台memcached做高可用,repcached版本的memcached之间会自动同步数据,以保持数据一致性,即使其中的一台memcached故障也不影响业务正常运行,故障的memcached修复上线后再自动从另外一台同步数据即可保持数据一致性。

haproxy:192.168.80.7
server1:192.168.80.10
server2:192.168.80.11
- server1 和 server2 可同时部署也可等server1部署好后 rsync -a /apps 192.168.80.11:/
-
- yum -y install gcc libevent libevent-devel
- wget https://jaist.dl.sourceforge.net/project/repcached/repcached/2.2.1-1.2.8/memcached-1.2.8-repcached-2.2.1.tar.gz
- tar xf memcached-1.2.8-repcached-2.2.1.tar.gz
- cd memcached-1.2.8-repcached-2.2.1
- ./configure --prefix=/apps/repcached --enable-replication
- make
-
- 会报错
- #报错如下

解决办法:
- vim memcached.c
-
- 56 #ifndef IOV_MAX
- 57 #if defined(__FreeBSD__) || defined(__APPLE__)
- 58 # define IOV_MAX 1024
- 59 #endif
- 60 #endif
-
-
- #改为如下内容,即删除原有的原第57,59行
- 56 #ifndef IOV_MAX
- 57 # define IOV_MAX 1024
- 58 #endif
再次编译安装:
- [root@localhost memcached-1.2.8-repcached-2.2.1]#make && make install
-
- 做软连接
- ln -s /apps/repcached/bin/memcached /usr/bin/
-
-
- 使用帮助
- [root@localhost ~]#memcached -h
- memcached 1.2.8
- repcached 2.2.1
-
- -x <ip_addr> hostname or IP address of peer repcached
- -X <num:num> TCP port number for replication. <listen:connect> (default: 11212)
server1
- #创建用户
- useradd -r -s /sbin/nologin memcached
-
- memcached -d -m 1024 -p 11211 -u memcached -c 2048 -x 192.168.80.11
- #-x 192.168.80.11 为对端memcached的地址 -d 后台
-
-
- ss -ntl
- # 查看是否启动
server2
- #在server1 上 将整个目录拷贝到 server2上(若server2已经完成部署不用拷贝)
- rsync -a /apps 192.168.91.101:/
- # apps注意不要加/
- #yum -y install gcc libevent libevent-devel
- #ln -s /apps/repcached/bin/memcached /usr/bin/
-
-
- useradd -r -s /sbin/nologin memcached
- #创建用户
-
-
- memcached -d -m 1024 -p 11211 -u memcached -c 2048 -x 192.168.80.10
-
-
- ss -ntl
- # 查看是否启动
haproxy
- yum install -y haproxy
- systemctl start haproxy
-
- vim /etc/haproxy/haproxy.cfg
-
- listen mem
- bind 192.168.80.7:11211
- mode tcp
- server m1 192.168.80.10:11211 check
- server m2 192.168.80.11:11211 check
-
- systemctl restart haproxy.service
测试:
- [root@localhost ~]#telnet 192.168.80.7 11211
- Trying 192.168.80.7...
- Connected to 192.168.80.7.
- Escape character is '^]'.
-
- set server 1 0 10
- hello word
- STORED
-
- get server
- VALUE server 1 10
- hello word
- END