# 第十四章:memcached
# memcached
### 什么是memcached:
1. `memcached`之前是`danga`的一个项目,最早是为LiveJournal服务的,当初设计师为了加速LiveJournal访问速度而开发的,后来被很多大型项目采用。官网是`www.danga.com`或者是`memcached.org`。
2. `Memcached`是一个高性能的**分布式**的**内存对象缓存**系统,全世界有不少公司采用这个缓存项目来构建大负载的网站,来分担数据库的压力。`Memcached`是通过在内存里维护一个统一的巨大的hash表,`memcached`能存储各种各样的数据,包括图像、视频、文件、以及数据库检索的结果等。简单的说就是将数据调用到内存中,然后从内存中读取,从而大大提高读取速度。
3. 哪些情况下适合使用`Memcached`:存储验证码(图形验证码、短信验证码)、登录session等所有不是至关重要的数据。
### 安装和启动`memcached`:
1. windows:
- 安装:`memcached.exe -d install`。
- 启动:`memcached.exe -d start`。
2. linux(ubuntu):
- 安装:`sudo apt install memcached`
- 启动:
```
<pre class="calibre12">```
cd /usr/local/memcached/bin
./memcached -d start
```
```
3. 可能出现的问题:
- 提示你没有权限:在打开cmd的时候,右键使用管理员身份运行。
- 提示缺少`pthreadGC2.dll`文件:将`pthreadGC2.dll`文件拷贝到`windows/System32`.
- 不要放在含有中文的路径下面。
4. 启动`memcached`:
- `-d`:这个参数是让`memcached`在后台运行。
- `-m`:指定占用多少内存。以`M`为单位,默认为`64M`。
- `-p`:指定占用的端口。默认端口是`11211`。
- `-l`:别的机器可以通过哪个ip地址连接到我这台服务器。如果是通过`service memcached start`的方式,那么只能通过本机连接。如果想要让别的机器连接,就必须设置`-l 0.0.0.0`。
如果想要使用以上参数来指定一些配置信息,那么不能使用`service memcached start`,而应该使用`/usr/bin/memcached`的方式来运行。比如`/usr/bin/memcached -u memcache -m 1024 -p 11222 start`。
### `telnet`操作`memcached`:
`telnet ip地址 [11211]`
1. 添加数据:
- `set`:
- 语法:```
<pre class="calibre12">```
set key flas(是否压缩) timeout value_length
value
```
```
- 示例:```
<pre class="calibre12">```
set username <span class="hljs-params">0</span> <span class="hljs-params">60</span> <span class="hljs-params">7</span>
zhiliao
```
```
- `add`:
- 语法:```
<pre class="calibre12">```
add key flas(<span class="hljs-params">0</span>) timeout value_length
value
```
```
- 示例:
```
<pre class="calibre12">```
add username <span class="hljs-params">0</span> <span class="hljs-params">60</span> <span class="hljs-params">7</span>
xiaotuo
```
```
`set`和`add`的区别:`add`是只负责添加数据,不会去修改数据。如果添加的数据的`key`已经存在了,则添加失败,如果添加的`key`不存在,则添加成功。而`set`不同,如果`memcached`中不存在相同的`key`,则进行添加,如果存在,则替换。
2. 获取数据:
- 语法:```
<pre class="calibre12">```
get key
```
```
- 示例:```
<pre class="calibre12">```
get username
```
```
3. 删除数据:
- 语法:```
<pre class="calibre12">```
delete key
```
```
- 示例:```
<pre class="calibre12">```
delete username
```
```
- `flush_all`:删除`memcached`中的所有数据。
4. 查看`memcached`的当前状态:
- 语法:`stats`。
### 通过`python`操作`memcached`:
1. 安装:`python-memcached`:`pip install python-memcached`。
2. 建立连接:
```
<pre class="calibre12">```
<span class="hljs-keyword">import</span> memcache
mc = memcache.Client([<span class="hljs-string">'127.0.0.1:11211'</span>,<span class="hljs-string">'192.168.174.130:11211'</span>],debug=<span class="hljs-keyword">True</span>)
```
```
3. 设置数据:
```
<pre class="calibre12">```
mc.set(<span class="hljs-string">'username'</span>,<span class="hljs-string">'hello world'</span>,time=<span class="hljs-params">60</span>*<span class="hljs-params">5</span>)
mc.set_multi({<span class="hljs-string">'email'</span>:<span class="hljs-string">'xxx@qq.com'</span>,<span class="hljs-string">'telphone'</span>:<span class="hljs-string">'111111'</span>},time=<span class="hljs-params">60</span>*<span class="hljs-params">5</span>)
```
```
4. 获取数据:
```
<pre class="calibre12">```
mc.get(<span class="hljs-string">'telphone'</span>)
```
```
5. 删除数据:
```
<pre class="calibre12">```
mc.delete(<span class="hljs-string">'email'</span>)
```
```
6. 自增长:
```
<pre class="calibre12">```
mc.incr(<span class="hljs-string">'read_count'</span>)
```
```
7. 自减少:
```
<pre class="calibre12">```
mc.decr(<span class="hljs-string">'read_count'</span>)
```
```
### memcached的安全性:
`memcached`的操作不需要任何用户名和密码,只需要知道`memcached`服务器的ip地址和端口号即可。因此`memcached`使用的时候尤其要注意他的安全性。这里提供两种安全的解决方案。分别来进行讲解:
1. 使用`-l`参数设置为只有本地可以连接:这种方式,就只能通过本机才能连接,别的机器都不能访问,可以达到最好的安全性。
2. 使用防火墙,关闭`11211`端口,外面也不能访问。
```
<pre class="calibre12">```
ufw enable # 开启防火墙
ufw disable # 关闭防火墙
ufw default deny # 防火墙以禁止的方式打开,默认是关闭那些没有开启的端口
ufw deny 端口号 # 关闭某个端口
ufw allow 端口号 # 开启某个端口
```
```
### 在Django中使用memcached:
首先需要在`settings.py`中配置好缓存:
```
<pre class="calibre12">```
CACHES = {
<span class="hljs-string">'default'</span>: {
<span class="hljs-string">'BACKEND'</span>: <span class="hljs-string">'django.core.cache.backends.memcached.MemcachedCache'</span>,
<span class="hljs-string">'LOCATION'</span>: <span class="hljs-string">'127.0.0.1:11211'</span>,
}
}
```
```
如果想要使用多台机器,那么可以在`LOCATION`指定多个连接,示例代码如下:
```
<pre class="calibre12">```
CACHES = {
<span class="hljs-string">'default'</span>: {
<span class="hljs-string">'BACKEND'</span>: <span class="hljs-string">'django.core.cache.backends.memcached.MemcachedCache'</span>,
<span class="hljs-string">'LOCATION'</span>: [
<span class="hljs-string">'172.19.26.240:11211'</span>,
<span class="hljs-string">'172.19.26.242:11211'</span>,
]
}
}
```
```
配置好`memcached`的缓存后,以后在代码中就可以使用以下代码来操作`memcached`了:
```
<pre class="calibre12">```
<span class="hljs-keyword">from</span> django.core.cache <span class="hljs-keyword">import</span> cache
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">index</span><span class="hljs-params">(request)</span>:</span>
cache.set(<span class="hljs-string">'abc'</span>,<span class="hljs-string">'zhiliao'</span>,<span class="hljs-params">60</span>)
print(cache.get(<span class="hljs-string">'abc'</span>))
response = HttpResponse(<span class="hljs-string">'index'</span>)
<span class="hljs-keyword">return</span> response
```
```
需要注意的是,`django`在存储数据到`memcached`中的时候,不会将指定的`key`存储进去,而是会对`key`进行一些处理。比如会加一个前缀,会加一个版本号。如果想要自己加前缀,那么可以在`settings.CACHES`中添加`KEY_FUNCTION`参数:
```
<pre class="calibre12">```
CACHES = {
<span class="hljs-string">'default'</span>: {
<span class="hljs-string">'BACKEND'</span>: <span class="hljs-string">'django.core.cache.backends.memcached.MemcachedCache'</span>,
<span class="hljs-string">'LOCATION'</span>: <span class="hljs-string">'127.0.0.1:11211'</span>,
<span class="hljs-string">'KEY_FUNCTION'</span>: <span class="hljs-keyword">lambda</span> key,prefix_key,version:<span class="hljs-string">"django:%s"</span>%key
}
}
```
```
- Introduction
- 第一章:学前准备
- 第一节:虚拟环境
- 第二节:准备工作
- 第三节:Django介绍
- 第四节:URL组成部分
- 第二章:URL与视图
- 第一节:第一个Django项目
- 第二节:视图与URL分发器
- 第三章:模板
- 第一节:模板介绍
- 第二节:模板变量
- 第三节:常用标签
- 第四节:常用过滤器
- 第五节:自定义过滤器
- 第七节:模版结构优化
- 第八节:加载静态文件
- 第四章:数据库
- 第一节:MySQL相关软件
- 第二节:数据库操作
- 第三节:ORM模型
- 第四节:模型常用字段
- 第五节:外键和表关系
- 第六节:增删改查操作
- 第七节:查询操作
- 第八节:QuerySet API
- 第九节:ORM模型迁移
- 第十节:ORM作业
- 第十一节:ORM作业参考答案
- 第十二节:Pycharm连接数据库
- 第五章:视图高级
- 第一节:限制请求method
- 第二节:页面重定向
- 第三节:HttpRequest对象
- 第四节:HttpResponse对象
- 第五节:生成CSV文件
- 第六节:类视图
- 第七节:错误处理
- 第六章:表单
- 第一节:表单概述
- 第二节:用表单验证数据
- 第三节:ModelForm
- 第四节:文件上传
- 第七章:cookie和session
- 第八章:上下文处理器和中间件
- 第一节:上下文处理器
- 第二节:中间件
- 第九章:安全
- 第一节:CSRF攻击
- 第二节:XSS攻击
- 第三节:点击劫持攻击
- 第四节:SQL注入
- 第十章:信号
- 第一节:什么是信号
- 第十一章:验证和授权
- 第一节:概述
- 第二节:用户对象
- 第三节:权限和分组
- 第十二章:Admin系统
- 第十三章:Django的缓存
- 第十四章:memcached
- 第十五章:Redis