MemCache--01 解决session
Posted 小鱼儿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MemCache--01 解决session相关的知识,希望对你有一定的参考价值。
1. MemCache介绍
Memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著。这是一套开放源代码软件,以BSD license授权发布。
MemCache的工作流程如下:
先检查客户端的请求数据是否在memcached中,如有,直接把请求数据返回,不再对数据库进行任何操作;
如果请求的数据不在memcached中,就去查数据库,把从数据库中获取的数据返回给客户端,同时把数据缓存一份到memcached中;每次更新数据库的同时更新memcached中的数据,保证一致性;
当分配给memcached内存空间用完之后,会使用LRU(Least Recently Used,最近最少使用)策略加上到期失效策略,失效数据首先被替换,然后再替换掉最近未使用的数据。
Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存中,然后从内存中读取,从而大大提高读取速度。
Memcached是以守护程序(监听)方式运行于一个或多个服务器中,随时会接收客户端的连接和操作。
在Memcached中可以保存的item数据量是没有限制的,只要内存足够
Memcached是一种无阻塞的socket通信方式服务,基于libevent库,由于无阻塞通信,对内存读写速度非常之快。Memcached分服务器端和客户端,可以配置多个服务器端和客户端,应用于分布式的服务非常广泛.`
Memcached作为小规模的数据分布式平台是十分有效果的。
Memcached是键值一一对应,key默认最大不能超过128个字
节,value默认大小是1M,也就是一个slabs,如果要存2M的值(连续的),不能用两个slabs,因为两个slabs不是连续的,无法在内存中
存储,故需要修改slabs的大小,多个key和value进行存储时,即使这个slabs没有利用完,那么也不会存放别的数据。Memcached已经可以支持C/C++、Perl、php、Python、Ruby、Java、C#、Postgres、Chicken Scheme、Lua、mysql和Protocol等语言客户端。
使用Memcache的网站一般流量都是比较大的,为了缓解数据库的压力,让Memcache作为一个缓存区域,把部分信息保存在内存中,在前端能够迅速的进行存取。那么一般的焦点就是集中在如何分担数据库压力和进行分布式,毕竟单台Memcache的内存容量是有限的
MemAdmin是一款可视化的Memcached管理与监控工具,使用PHP开发,体积小,操作简单。
Memcache与Redis的区别?
1.存储方式
#Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。 Redis有部份存在硬盘上,这样能保证数据的持久性。 不过Memcache还可以缓存其他东西,图片视频等。
2.数据支持类型
#Memcache对数据类型支持相对简单,只支持k-v结构。 Redis有复杂的数据类型支持五种数据类型:字符串,列表,哈希,集合,有序集合。。
3.使用底层模型不同
#它们之间底层实现方式以及与客户端之间通信的应用协议不一样。 Redis直接自己构建了VM机制 因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
4.value大小
#Redis最大可以达到1GB,而Memcache只有1MB
5.数据恢复
#Memcache挂掉后,数据不可恢复,Redis数据丢失后可以通过AOF日志恢复。
6.应用场景不同
#Redis除啦作为数据库使用之外,还能做消息队列,数据堆栈和数据缓存等,Memcache适用于缓存sql语句,数据集,用户临时性数据,延迟查询数据 session等。
使用场景
#1、如果有持久方面的需求或对数据类型和处理有要求的应该选择redis。 2、如果简单的key/value 存储应该选择memcached。 在电子商务类的网站中,一般都有分类,然后还有搜索结果列表。针对这种情况下,我们对分类的数据,可以使用Memcached,因为分类数据一般不会改变,读多写少,直接存储在memcached中,每次查询都只需要从memcached中获取就可以了。
2.Session与Cookie介绍
1) 、Session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构来保存信息。
当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为session id),如果已包含则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(检索不到,会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。
保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。一般这个cookie的名字都是类似于SEEESIONID。但cookie可以被人为的禁止,则必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。
经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面。还有一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。
2)、 Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送至同一个服务器。网络服务器用HTTP头向客户端发送cookies,在客户终端,浏览器解析这些cookies并将它们保存为一个本地文件,它会自动将同一服务器的任何请求缚上这些cookies。
具体来说cookie机制采用的是在客户端保持状态的方案。它是在用户端的会话状态的存贮机制,他需要用户打开客户端的cookie支持。cookie的作用就是为了解决HTTP协议无状态的缺陷所作的努力。
正统的cookie分发是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie。然而纯粹的客户端脚本如javascript也可以生成cookie。而cookie的使用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器检查所有存储的cookie,如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置,则把该cookie附在请求资源的HTTP请求头上发送给服务器。
3)、总结一下:
- Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中;
- Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。
Session共享问题?
session主要用于服务端存储用户会话信息,cookie用于浏览器存储用户会话信息。单系统服务session都存在同一个web容器中,例如tomcat中,用户请求都只访问这个容器中的session信息,除非容器挂了,否则不存在session取不到的情况。随着业务的扩展,应用用户的增加,单个容器存放系统应用消耗服务的cup和内存会不断增加,导致应用性能下降。此时考虑用nginx集群做应用的负载均衡请求分发,假设用ngnix集群三个服务,分别用A、B、C表示。按照未做session共享,仍然使用Servlet中HttpSession情景,假设此时访问的是A服务,那么session将存储在A服务中,此处如果A服务宕机,ngnix会将用户的请求分发到B或者C服务,但是B和C服务中没有存A存放的Session信息,那么用户访问的数据将会丢失。为了解决session数据丢失,需要将session共享,主流做法是将session存储在nosql数据库中,例如memcache、redis等。也有很多人通过spring session 实现共享,原理大致一样,下面主要实现了memcache缓存session共享。
3. 安装部署Nginx
#1.配置Nginx官方yum仓库
cat >/etc/yum.repos.d/nginx.repo<<\'EOF\'
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
EOF
#2.安装Nginx
[root@web01 ~]# yum install -y nginx
#3.配置Nginx进程运行用户
[root@web01 ~]# groupadd -g666 www
[root@web01 ~]# useradd -u666 -g666 www
[root@web01 ~]# sed -i \'/^user/c user www;\' /etc/nginx/nginx.conf
#4.启动Nginx,并将Nginx加入开机自启
[root@web01 ~]# systemctl start nginx
[root@web01 ~]# systemctl enable nginx
4. 安装部署PHP
#1.清除默认的版本
[root@web01 ~]# yum remove php-mysql-5.4 php php-fpm php-common
#更新官方源
[root@nginx ~]# vim /etc/yum.repos.d/php.repo
[php-webtatic]
name = PHP Repository
baseurl = http://us-east.repo.webtatic.com/yum/el7/x86_64/
gpgcheck = 0
#2.安装PHP及其依赖和PHP的memcache的扩展插件
[root@web01 ~]# yum -y install php71w php71w-cli php71w-common php71w-devel php71w-embedded php71w-gd php71w-mcrypt php71w-mbstring php71w-pdo php71w-xml php71w-fpm php71w-mysqlnd php71w-opcache php71w-pecl-memcached
#3.配置php-fpm用户与Nginx的运行用户保持一致
[root@web01 ~]# sed -i \'/^user/c user = www\' /etc/php-fpm.d/www.conf
[root@web01 ~]# sed -i \'/^group/c group = www\' /etc/php-fpm.d/www.conf
#4.启动php-fpm,并将其加入开机自启
[root@web01 ~]# systemctl start php-fpm
[root@web01 ~]# systemctl enable php-fpm
5. 安装Mariadb数据库
#1.下载安装
[root@db01 ~]# yum install -y mariadb mariadb-server
#2.启动Mariadb数据库, 并加入开机自动
[root@db01 ~]# systemctl start mariadb
[root@db01 ~]# systemctl enable mariadb
#3.给Mariadb配置登陆密码,并是新密码进行登录数据库
[root@db01 ~]# mysqladmin password \'qls123.com\'
[root@db01 ~]# mysql -uroot -pqls123.com
Welcome to the MariaDB monitor. Commands end with ; or \\g.
Your MariaDB connection id is 6
Server version: 5.5.64-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type \'help;\' or \'\\h\' for help. Type \'\\c\' to clear the current input statement.
MariaDB [(none)]>
#4.创建一个可以远程连接的用户
MariaDB [(none)]> grant all privileges on *.* to qls@\'10.0.0.%\' identified by \'123\';
Query OK, 0 rows affected (0.01 sec)
6. 部署网站(phpMyAdmin)
#1.创建一个虚拟主机配置文件
[root@web01 ~]# cat /etc/nginx/conf.d/phpmyadmin.com.conf
server {
listen 80;
server_name php.gjy.com;
root /code/phpmyadmin;
client_max_body_size 100m;
location / {
index index.php index.html;
}
location ~ \\.php$ {
root /code/phpmyadmin;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
#2.检查语法和重启nginx服务
[root@web01 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web01 ~]# systemctl reload nginx
#3.#下载软件
[root@web01 ~]# wget https://files.phpmyadmin.net/phpMyAdmin/5.0.0-rc1/phpMyAdmin-5.0.0-rc1-all-languages.zip
#4.进行解压
[root@web01 ~]# unzip phpMyAdmin-5.0.0-rc1-all-languages.zip
#5.移动到指定的站点目录中
[root@web01 ~]# mv phpMyAdmin-5.0.0-rc1-all-languages /code/phpmyadmin
#6.授权为www用户所有
[root@web01 ~]# chown -R www.www /code/phpmyadmin
#7.本地hosts文件域名解析并访问
10.0.0.7 php.gjy.com
#8.报错,session目录权限不足,添加权限
[root@web01 ~]# chown -R www.www /var/lib/php/session/
#9.配置phpmyadmin的配置文件
[root@web01 ~]# cd /code/phpmyadmin/
[root@web01 /code/phpmyadmin]# cp config.sample.inc.php config.inc.php
[root@web01 /code/phpmyadmin]# vim config.inc.php
$cfg[\'Servers\'][$i][\'host\'] = \'10.0.0.51\';
#10.注意:以上的环境web01和web02是一致的。部署站点的时候可以将web01的打包发给web02
#打包进行传输
[root@web01 ~]# tar zcf phpmyadmin.tar.gz /code/phpmyadmin
[root@web01 ~]# scp -rp phpmyadmin.tar.gz root@10.0.0.8:/root
[root@web01 ~]# scp -rp /etc/nginx/conf.d/phpmyadmin.com.conf root@10.0.0.8:/etc/nginx/conf.d/
#11.web02主机操作
[root@web02 ~]# tar xf phpmyadmin.tar.gz -C /
[root@web02 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web02 ~]# systemctl reload nginx
12.访问测试
#13.本地查看cookies值
[root@web02 /code/phpmyadmin]# ll /var/lib/php/session
total 4
-rw------- 1 www www 2451 2019-12-07 14:41 sess_9e987efb4f8ee67822ca36e2d28cc21e
7. 部署负载均衡
#1.配置nginx官方源
[root@lb01 ~]# vim /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
#2.下载安装nginx
[root@lb01 ~]# yum install nginx -y
#3.启动nginx
[root@lb01 ~]# systemctl start nginx
[root@lb01 ~]# systemctl enable nginx
#4.配置负载均衡配置文件
[root@lb01 ~]# cat /etc/nginx/conf.d/node_proxy.conf
upstream php {
server 172.16.1.7:80;
server 172.16.1.8:80;
}
server {
listen 80;
server_name phpmyadmin.qls.com;
location / {
proxy_pass http://php;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
#5.重启nginx
[root@lb01 ~]# systemctl reload nginx
#6.本地hosts文件解析
10.0.0.6 phpmyadmin.qls.com
#7.浏览器登录访问
确认访问域名时走的是负载均衡。这时你会发现,在你用户和密码都正确的情况下,你是登录不成功的。所以,接下来要做的就是session会话共享。
8. 部署Memcached
#1.安装依赖
[root@db01 ~]# yum install libevent libevent-devel nc -y
#2.安装Memcached
[root@db01 ~]# yum install memcached -y
#3.启动memcached
[root@db01 ~]# systemctl start memcached
[root@db01 ~]# systemctl enable memcached
#查看是否启动成功
[root@db01 ~]# netstat -lntp |grep 11211
tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN 9072/memcached
tcp6 0 0 :::11211 :::* LISTEN 9072/memcached
#4.安装PHP memcache扩展插件
[root@web01 ~]# yum install -y git
[root@web01 ~]# git clone https://github.com/websupport-sk/pecl-memcache.git
[root@web01 ~]# cd pecl-memcache/
[root@web01 ~/pecl-memcache]# git checkout php7
#5.安装扩展库
[root@web01 ~/pecl-memcache]# phpize
Configuring for:
PHP Api Version: 20100412
Zend Module Api No: 20100525
Zend Extension Api No: 220100525
#6.初始化和编译安装
[root@web01 ~/pecl-memcache]# ./configure
[root@web01 ~/pecl-memcache]# make
[root@web01 ~/pecl-memcache]# make install
Installing shared extensions: /usr/lib64/php/modules/
#7.配置memcache客户端使其生效
[root@web01 ~/pecl-memcache]# tail -2 /etc/php.ini
extension_dir = "/usr/lib64/php/modules/"
extension = memcache.so
#8.重启php
[root@web01 ~/pecl-memcache]# systemctl restart php-fpm.service
#9.查看PHP的web界面配置信息
[root@web01 ~/pecl-memcache]# vim /code/phpmyadmin/info.php
<?php
phpinfo();
?>
[root@web01 phpmyadmin]# chown www.www info.php
10.浏览器解析本主机进行查看
png)
#11.编写测试memcache文件
[root@web01 ~]# cat>/code/phpmyadmin/test_memcache.php<<"EOF"
<?php
$memcache = new Memcache;
$memcache->connect(\'172.16.1.51\', 11211) or die ("Could not connect server");
$memcache->set(\'key\', \'Memcache connect OK\');
$get = $memcache->get(\'key\');
echo $get;
?>
EOF
[root@web01 ~]# php /code/phpmyadmin/test_memcache.php
Memcache connect OK[root@web01 ~]#
#12.修改php配置(设置session共享)
[root@web01 ~]# vim /etc/php.ini
session.save_handler = memcache
session.save_path = "tcp://172.16.1.51:11211"
#把最后两行注释掉,session存放的路径
[root@web01 ~]# vim /etc/php-fpm.d/www.conf
;php_value[session.save_handler] = files
;php_value[session.save_path] = /var/lib/php/session
#13.重启php
[root@web01 ~]# systemctl restart php-fpm.service
#14.浏览器重新刷新查看session的位置已经改变了
#15.将配置传输到web02主机
[root@web01 ~]# scp -rp memcache.tar.gz 10.0.0.8:/root
#web02主机操作
[root@web02 ~]# tar xf memcache.tar.gz
[root@web02 ~]# cd pecl-memcache/
[root@web02 ~/pecl-memcache]# git checkout php7
[root@web02 ~/pecl-memcache]# phpize
Configuring for:
PHP Api Version: 20160303
Zend Module Api No: 20160303
Zend Extension Api No: 320160303
#下载依赖
[root@web02 ~/pecl-memcache]# yum install -y zlib zlib-devel
[root@web02 ~/pecl-memcache]# ./configure
[root@web02 ~/pecl-memcache]# make
[root@web02 ~/pecl-memcache]# make install
Installing shared extensions: /usr/lib64/php/modules/
#web01主机操作
[root@web01 ~]# scp -rp /etc/php.ini 10.0.0.8:/etc/php.ini
[root@web01 ~]# scp -rp /etc/php-fpm.d/www.conf 10.0.0.8:/etc/php-fpm.d/www.conf
#web02主机重启php
[root@web02 ~/pecl-memcache]# systemctl restart php-fpm.service
#16.修改本地主机解析
10.0.0.6 php.gjy.com
17.浏览器登录测试 php.gjy.com
#18.登录memcache数据库
[root@db01 ~]# telnet 127.0.0.1 11211
stats items #列出所有的key
stats cachedump 16 0 #列出对应的key值
ITEM 564791a36f16534f7faacf66e29a93b8 [2497 b; 1576087328 s]
以上是关于MemCache--01 解决session的主要内容,如果未能解决你的问题,请参考以下文章
解决Cannot find class [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter](代码片
解决Cannot find class [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter](代码片
from torchtext.datasets import text_classification 报错解决:cannot import name ‘text_classification‘(代码片
解决报错:在Python中使用property装饰器时,出现错误:TypeError: descriptor ‘setter‘ requires a ‘property‘ object but(代码片