【0711】NoSQL——memcached

21.1 nosql介紹php

什麼是 NoSQL?html

  • 非關係型數據庫就是 NoSQL,關係型數據庫表明 MySQLmysql

  • 對於關係型數據庫來講,是須要把數據存儲到庫、表、行、字段裏,查詢的時候根據條件一行一行地去匹配,當量很是大的時候就很耗費時間和資源,尤爲是數據是須要從磁盤裏去檢索linux

  • NoSQL 數據庫存儲原理很是簡單(典型的數據類型爲 k-v ),不存在繁雜的關係鏈,好比mysql查詢的時候,須要找到對應的庫、表(一般是多個表)以及字段。nginx

  • NoSQL 數據能夠存儲在內存裏,查詢速度很是快web

  • NoSQL 在性能表現上雖然能優於關係型數據庫,可是它並不能徹底替代關係型數據庫redis

  • NoSQL 由於沒有複雜的數據結構,擴展很是容易,支持分佈式算法

常見的 NoSQL 數據庫:sql

  • k-v 形式的:memcached、redis 適合儲存用戶信息,好比會話、配置文件、參數、購物車等等。這些信息通常都和ID(鍵)掛鉤,這種情景下鍵值數據庫是個很好的選擇。mongodb

  • 文檔數據庫:mongodb 將數據以文檔的形式儲存。每一個文檔都是一系列數據項的集合。每一個數據項都有一個名稱與對應的值,值既能夠是簡單的數據類型,如字符串、數字和日期等;也能夠是複雜的類型,若有序列表和關聯對象。數據存儲的最小單位是文檔,同一個表中存儲的文檔屬性能夠是不一樣的,數據可使用 XML、JSON 或者 JSONB 等多種形式存儲。

  • 列存儲 Hbase

  • 圖  Neo4J、Infinite Graph、OrientDB


21.2 memrcached介紹

  • Memcached 是國外社區網站 LiveJournal 團隊開發,目的是爲了經過緩存數據庫查詢結果,減小數據庫訪問次數,從而提升動態web站點性能。

  • 官方站點 http://www.memcached.org/ 

  • 數據結構簡單(k-v),數據存放在內存裏

  • 多線程

  • 基於 c/s 架構,協議簡單

  • 基於 libevent 的事件處理

  • 自主內存存儲處理(slab allowcation)

  • 數據過時方式:Lazy Expiration 和 LRU

Memcached 的數據流向:

11.png

Slab allocation:

Slab Allocation 的原理:

  • 將分配的內存分割成各類尺寸的塊(chunk), 並把尺寸相同的塊分紅組(chunk的集合),每一個chunk集合被稱爲slab。

  • Memcached 的內存分配以 Page 爲單位,Page 默認值爲1M,能夠在啓動時經過 -I 參數來指定。

  • Slab是由多個 Page 組成的,Page 按照指定大小切割成多個 chunk。

12.png

Growth factor:

  • Memcached 在啓動時經過 -f 選項能夠指定 Growth Factor 因子。該值控制 chunk 大小的差別。默認值爲1.25。

  • 經過 memcached-tool 命令查看指定 Memcached 實例的不一樣 slab 狀態,能夠看到各 Item所佔大小(chunk大小)差距爲1.25

  • 命令:# memcached-tool 127.0.0.1:11211 display

Memcached 的數據過時方式:

  • Lazy Expiration:

Memcached 內部不會監視記錄是否過時,而是在 get 時查看記錄的時間戳,檢查記錄是否過時。這種技術被稱爲 lazy(惰性)expiration。所以,Memcached 不會在過時監視上耗費 CPU 時間。

  • LRU:

Memcached 會優先使用已超時的記錄的空間,但即便如此,也會發生追加新記錄時空間不足的狀況,此時就要使用名爲 Least Recently Used(LRU)機制來分配空間。顧名思義,這是刪除「最近最少使用」的記錄的機制。所以,當內存空間不足時(沒法從 slab class 獲取到新的空間時),就從最近未被使用的記錄中搜索,並將其空間分配給新的記錄。從緩存的實用角度來看,該模型十分理想。


21.3 安裝memcached

一、安裝:yum install -y memcached

二、啓動:systemctl start memcached

三、查看進程及端口:

[root@arslinux-01 ~]# ps aux|grep memcached
memcach+   8981  0.0  0.1 344092  1680 ?        Ssl  21:07   0:00 /usr/bin/memcached -u memcached -p 11211 -m 64 -c 1024
root       9003  0.0  0.0 112724   984 pts/0    R+   21:07   0:00 grep --color=auto memcached
[root@arslinux-01 ~]# netstat -lntp|grep memcached
tcp        0      0 0.0.0.0:11211           0.0.0.0:*               LISTEN      8981/memcached
tcp6       0      0 :::11211                :::*                    LISTEN      8981/memcached
/usr/bin/memcaced:

-u    指定運行 memcached 服務的用戶

-p    指定監聽端口

-m    指定 memcached分配內存(單位M)

-c    指定最大併發數

如何改參數?

一、用命令行啓動,在啓動時更改參數

二、更改 /etc/sysconfig/memcached 參數

[root@arslinux-01 ~]# cat /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS=""

好比加上監聽的ip,能夠把OPTIONS="" 改成OPTIONS="127.0.0.1"


21.4 查看memcached狀態

一、memcached -tool 工具

[root@arslinux-01 ~]# memcached-tool 127.0.0.1:11211 stats
#127.0.0.1:11211   Field       Value
accepting_conns           1
auth_cmds           0
auth_errors           0
bytes           0
bytes_read           7
bytes_written           0
cas_badval           0
cas_hits           0
cas_misses           0
cmd_flush           0
cmd_get           0
cmd_set           0
cmd_touch           0
conn_yields           0
connection_structures          11
curr_connections          10
curr_items           0
decr_hits           0
decr_misses           0
delete_hits           0
delete_misses           0
evicted_unfetched           0
evictions           0
expired_unfetched           0
get_hits           0
get_misses           0
hash_bytes      524288
hash_is_expanding           0
hash_power_level          16
incr_hits           0
incr_misses           0
libevent 2.0.21-stable
limit_maxbytes    67108864
listen_disabled_num           0
pid        8981
pointer_size          64
reclaimed           0
reserved_fds          20
rusage_system    0.065852
rusage_user    0.025768
threads           4
time  1562851027
total_connections          11
total_items           0
touch_hits           0
touch_misses           0
uptime         605
version      1.4.15

平時關注 get_hits ÷ curr_items 的值

二、nc 命令

1)安裝 nc 命令

[root@arslinux-01 ~]# yum install -y nc

2)使用方法

[root@arslinux-01 ~]# echo stats |nc 127.0.0.1 11211
STAT pid 8981
STAT uptime 1325
STAT time 1562851747
STAT version 1.4.15
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT rusage_user 0.050529
STAT rusage_system 0.097691
STAT curr_connections 10
STAT total_connections 12
STAT connection_structures 11
STAT reserved_fds 20
STAT cmd_get 0
STAT cmd_set 0
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 0
STAT get_misses 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 auth_cmds 0
STAT auth_errors 0
STAT bytes_read 13
STAT bytes_written 1024
STAT limit_maxbytes 67108864
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT bytes 0
STAT curr_items 0
STAT total_items 0
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT evictions 0
STAT reclaimed 0
END

三、memstat 命令

1)安裝 libmemcached

[root@arslinux-01 ~]# yum install -y libmemcached

2)使用方法

[root@arslinux-01 ~]# memstat --servers 127.0.0.1:11211
Server: 127.0.0.1 (11211)
pid: 8981
uptime: 1625
time: 1562852047
version: 1.4.15
libevent: 2.0.21-stable
pointer_size: 64
rusage_user: 0.058228
rusage_system: 0.119882
curr_connections: 10
total_connections: 13
connection_structures: 11
reserved_fds: 20
cmd_get: 0
cmd_set: 0
cmd_flush: 0
cmd_touch: 0
get_hits: 0
get_misses: 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: 30
bytes_written: 2069
limit_maxbytes: 67108864
accepting_conns: 1
listen_disabled_num: 0
threads: 4
conn_yields: 0
hash_power_level: 16
hash_bytes: 524288
hash_is_expanding: 0
bytes: 0
curr_items: 0
total_items: 0
expired_unfetched: 0
evicted_unfetched: 0
evictions: 0
reclaimed: 0

總結:

能夠查看 Memcached 狀態的方法:

一、memcached-tool 127.0.0.1:11211 stats

二、echo stats | nc 127.0.0.1 11211

三、memstat --servers 127.0.0.1:11211


21.5 memcached命令行

[root@arslinux-01 ~]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
set key2 0 30 2
12
STORED
set key1 0 20 3
abc
STORED
get key1
VALUE key1 0 3
abc
END
get key2
END

set key名 過時時間 value的值

Memcached 語法規則:

  • <command name> <key> <flags> <exptime> <bytes>\r\n <data block>\r\n

注:\r\n在windows下是Enter鍵

  • <command name> 能夠是set, add, replace

set 表示按照相應的 <key> 存儲該數據,沒有的時候增長,有的時候覆蓋

add 表示按照相應的 <key> 添加該數據,可是若是該 <key> 已經存在則會操做失敗

replace 表示按照相應的 <key> 替換數據,可是若是該 <key> 不存在則操做失敗。

  • <key> 客戶端須要保存數據的key

  • <flags> 是一個16位的無符號的整數(以十進制的方式表示)。該標誌將和須要存儲的數據一塊兒存儲,並在客戶端get數據時返回。客戶端能夠將此標誌用作特殊用途,此標誌對服務器來講是不透明的。

  • <exptime> 爲過時的時間。若爲0表示存儲的數據永遠不過時(但可被服務器算法:LRU 等替換)。若是非0(unix時間或者距離此時的秒數),當過時後,服務器能夠保證用戶得不到該數據(以服務器時間爲標準)。

  • <bytes> 須要存儲的字節數,當用戶但願存儲空數據時 <bytes> 能夠爲0

  • <data block> 須要存儲的內容,輸入完成後,最後客戶端須要加上\r\n(直接點擊Enter)做爲結束標誌。

Memcached數據示例:

set key3 1 100 4

1234

STORED

get key3

VALUE key3 1 4

1234

END

replace key3 1 0 5

abcde

STORED

get key3

VALUE key3 1 5

abcde

END

delete key3

DELETED

get key3

END

21.6 memcached數據導出和導入

memcached 重啓以前最好數據導出,待重啓後再導入

導出:

[root@arslinux-01 ~]# memcached-tool 127.0.0.1:11211 dump > data.txt
Dumping memcache contents
Number of buckets: 1
Number of items  : 3
Dumping bucket 1 - 3 total items

導入:

[root@arslinux-01 ~]# nc 127.0.0.1 11211 < data.txt
NOT_STORED
NOT_STORED
NOT_STORED

之因此顯示 NOT_STORED,是由於以前數據時 add 添加的,數據導入沒法覆蓋

所以能夠重啓 memcached ,清空數據後再導入

[root@arslinux-01 ~]# systemctl restart memcached
[root@arslinux-01 ~]# nc 127.0.0.1 11211 < data.txt
STORED
STORED
STORED

不過實際上,數據並無導入 memcached

由於 data.txt 裏的時間戳已通過期

[root@arslinux-01 ~]# cat data.txt
add k1 1 1562850422 5
12345
add name 1 1562850422 6
amings
add age 1 1562850422 2
20
[root@arslinux-01 ~]# date -d @1562850422
2019年 07月 11日 星期四 21:07:02 CST
[root@arslinux-01 ~]# date
2019年 07月 11日 星期四 22:23:49 CST

那麼須要更改 data.txt 中的時間戳,以後再從新導入

[root@arslinux-01 ~]# date -d "+1 hour" +%s
1562858838
[root@arslinux-01 ~]# vim data.txt
add k1 1 1562858838 5
12345
add name 1 1562858838 6
amings
add age 1 1562858838 2
20
[root@arslinux-01 ~]# systemctl restart memcached
[root@arslinux-01 ~]# nc 127.0.0.1 11211 < data.txt
STORED
STORED
STORED
[root@arslinux-01 ~]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
get k1
VALUE k1 1 5
12345
END
get name
VALUE name 1 6
amings
END
get age
VALUE age 1 2
20
END


21.7 php 鏈接 memcached

一、先安裝 php 的 memcached 擴展

[root@arslinux-01 ~]# cd /usr/local/src/
[root@arslinux-01 src]# wget http://www.apelearn.com/bbs/data/attachment/forum/memcache-2.2.3.tgz
[root@arslinux-01 src]# tar xvf memcache-2.2.3.tgz
package.xml
memcache-2.2.3/config.m4
memcache-2.2.3/config9.m4
memcache-2.2.3/config.w32
memcache-2.2.3/CREDITS
memcache-2.2.3/example.php
memcache-2.2.3/memcache.c
memcache-2.2.3/memcache_queue.c
memcache-2.2.3/memcache_session.c
memcache-2.2.3/memcache_standard_hash.c
memcache-2.2.3/memcache_consistent_hash.c
memcache-2.2.3/memcache.dsp
memcache-2.2.3/php_memcache.h
memcache-2.2.3/memcache_queue.h
memcache-2.2.3/README
[root@arslinux-01 src]# cd memcache-2.2.3/
[root@arslinux-01 memcache-2.2.3]# /usr/local/php-fpm/bin/phpize //生成 config 文件
Configuring for:
PHP Api Version:         20131106
Zend Module Api No:      20131226
Zend Extension Api No:   220131226
Cannot find autoconf. Please check your autoconf installation and the
$PHP_AUTOCONF environment variable. Then, rerun this script.

出現以上錯誤,須要安裝 autoconf ,能夠 yum 安裝

[root@arslinux-01 memcache-2.2.3]# yum install -y autoconf
[root@arslinux-01 memcache-2.2.3]# /usr/local/php-fpm/bin/phpize
Configuring for:
PHP Api Version:         20131106
Zend Module Api No:      20131226
Zend Extension Api No:   220131226
[root@arslinux-01 memcache-2.2.3]# ./configure --with-php-config=/usr/local/php-fpm/bin/php-config
[root@arslinux-01 memcache-2.2.3]# make && make install

完成安裝後,最後會有如下提示,說明模塊安裝的位置

Installing shared extensions:     /usr/local/php-fpm/lib/php/extensions/no-debug-non-zts-20131226/
[root@arslinux-01 memcache-2.2.3]# ls /usr/local/php-fpm/lib/php/extensions/no-debug-non-zts-20131226/
memcache.so  opcache.a  opcache.so

已生成 memcached.so 模塊

二、編輯 php.ini 文件,添加 extension=php_memcached.dll

[root@arslinux-01 memcache-2.2.3]# vim /usr/local/php-fpm/etc/php.ini
extension=memcache.so

三、查看 php-fpm 模塊是否存在

[root@arslinux-01 memcache-2.2.3]# /usr/local/php-fpm/bin/php -m|grep memcache
memcache

四、測試

[root@arslinux-01 ~]# curl www.apelearn.com/study_v2/.memcache.txt > 1.php 2>/dev/null
[root@arslinux-01 ~]# cat 1.php
<?php
//鏈接Memcache Memcache
$mem = new Memcache;
$mem->connect("localhost", 11211);
//保存數據
$mem->set('key1', 'This is first value', 0, 60);
$val = $mem->get('key1');
echo "Get key1 value: " . $val ."<br>";
//替換數據
$mem->replace('key1', 'This is replace value', 0, 60);
$val = $mem->get('key1');
echo "Get key1 value: " . $val . "<br>";
//保存數組數據
$arr = array('aaa', 'bbb', 'ccc', 'ddd');
$mem->set('key2', $arr, 0, 60);
$val2 = $mem->get('key2');
echo "Get key2 value: ";
print_r($val2);
echo "<br>";
//刪除數據
$mem->delete('key1');
$val = $mem->get('key1');
echo "Get key1 value: " . $val . "<br>";
//清除全部數據
$mem->flush();
$val2 = $mem->get('key2');
echo "Get key2 value: ";
print_r($val2);
echo "<br>";
//關閉鏈接
$mem->close();
?>
[root@arslinux-01 ~]# /usr/local/php-fpm/bin/php 1.php
Get key1 value: This is first value<br>Get key1 value: This is replace value<br>Get key2 value: Array
(
[0] => aaa
[1] => bbb
[2] => ccc
[3] => ddd
)
<br>Get key1 value: <br>Get key2 value: <br>[root@arslinux-01 ~]#

或者將1.php放到某個虛擬主機根目錄下面,在瀏覽器訪問,便可看到效果

最終能夠看到數據以下就是成功了


21.8 memcached 中存儲 sessions

一、下載 php 測試文件

[root@arslinux-01 ~]# wget http://study.lishiming.net/.mem_se.txt
[root@arslinux-01 ~]# cat .mem_se.txt
<?php
session_start();
if (!isset($_SESSION['TEST'])) {
$_SESSION['TEST'] = time();
}
$_SESSION['TEST3'] = time();
print $_SESSION['TEST'];
print "<br><br>";
print $_SESSION['TEST3'];
print "<br><br>";
print session_id();
?>

二、查看 nginx 默認虛擬主機的文件夾

[root@arslinux-01 ~]# cat /usr/local/nginx/conf/vhost/
aaa.com.conf   load.conf      proxy.conf     ssl.conf       test.com.conf
[root@arslinux-01 ~]# cat /usr/local/nginx/conf/vhost/aaa.com.conf
server
{
listen 80 default_server;
server_name aaa.com;
index index.html index.htm index.php;
root /data/wwwroot/default;
location ~ \.php$
{
include fastcgi_params;
fastcgi_pass unix:/tmp/arslinux.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /data/wwwroot/default.com$fastcgi_script_name;
}
}

三、將.mem_se.txt 拷到 /data/wwwroot/default 下

[root@arslinux-01 ~]# cd /data/wwwroot/default/
[root@arslinux-01 default]# cp /root/.mem_se.txt 1.php
[root@arslinux-01 default]# ls
1.php  index.html
[root@arslinux-01 default]# curl localhost/1.php
File not found.

★★★查看了默認虛擬服務器配置文件,看到/data/wwwroot/default.com$fastcgi_script_name,所以目錄文件名臣不對,更更名稱後,正常

[root@arslinux-01 wwwroot]# mv default/ default.com/
[root@arslinux-01 wwwroot]# curl localhost/1.php
1562859350<br><br>1562859350<br><br>hldn2qa8n3kmel8tiieckqoj17
[root@arslinux-01 wwwroot]# ll /tmp/ |grep sess
-rw------- 1 php-fpm php-fpm 37 7月  11 23:35 sess_hldn2qa8n3kmel8tiieckqoj17
[root@arslinux-01 wwwroot]# curl localhost/1.php
1562859435<br><br>1562859435<br><br>593f6g4rk451qq0310840boqc0
[root@arslinux-01 wwwroot]# ll /tmp/ |grep sess
-rw------- 1 php-fpm php-fpm 37 7月  11 23:37 sess_593f6g4rk451qq0310840boqc0
-rw------- 1 php-fpm php-fpm 37 7月  11 23:35 sess_hldn2qa8n3kmel8tiieckqoj17

四、若是不想將 session 存在 /tmp/ 下,而是存在 memcached 裏

那麼編輯 php.ini

[root@arslinux-01 wwwroot]# vim /usr/local/php-fpm/etc/php.ini
session.save_handler = memcache                            //指定存儲類型
session.save_path = "tcp://192.168.194.130:11211"         //指定 memcached 服務器的ip和端口

五、重啓 php-fpm,刪除 /tmp/下的 session 文件

[root@arslinux-01 wwwroot]# /etc/init.d/php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm  done
[root@arslinux-01 wwwroot]# rm -f /tmp/sess_*

六、再 curl 1.php,而 /tmp/ 下已經沒有 session 文件生成了

[root@arslinux-01 wwwroot]# curl localhost/1.php
1562859940<br><br>1562859940<br><br>nf6tt9itt401oq9j7p92rf3663
[root@arslinux-01 wwwroot]# ll /tmp/ |grep sess

七、session 存到了 memcached 裏面

[root@arslinux-01 wwwroot]# curl localhost/1.php
1562860064<br><br>1562860064<br><br>52ofaaoorjjbg4n308tq80kch2

八、直接在 memcached 中查看不了,由於不知道 key

因此能夠先 dump 出來,能夠看到 key

[root@arslinux-01 wwwroot]# memcached-tool 127.0.0.1:11211 dump >data1.txt
Dumping memcache contents
Number of buckets: 1
Number of items  : 2
Dumping bucket 3 - 2 total items
[root@arslinux-01 wwwroot]# cat data1.txt
add 52ofaaoorjjbg4n308tq80kch2 0 1562861504 37
TEST|i:1562860064;TEST3|i:1562860064;
add nf6tt9itt401oq9j7p92rf3663 0 1562861380 37
TEST|i:1562859940;TEST3|i:1562859940;

或者:

httpd.conf 中對應的虛擬主機中添加(若是安裝的是 apache)

php_value session.save_handler "memcache" php_value session.save_path "tcp://192.168.0.9:11211" 

或者:

php-fpm.conf 對應的pool中添加(pool 在 /usr/local/php-fpm/etc/php-fpm.d/ 下)

php_value[session.save_handler] = memcache

php_value[session.save_path] = " tcp://192.168.0.9:11211 "

九、從新測試

[root@arslinux-01 wwwroot]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
get 52ofaaoorjjbg4n308tq80kch2
VALUE 52ofaaoorjjbg4n308tq80kch2 0 37
TEST|i:1562860064;TEST3|i:1562860064;
END
get nf6tt9itt401oq9j7p92rf3663
VALUE nf6tt9itt401oq9j7p92rf3663 0 37
TEST|i:1562859940;TEST3|i:1562859940;
END

數值一致,成功!!!

相關文章
相關標籤/搜索