(操作系统:UOS 20 Home)
1、NoSQL:Not only SQL
sql数据库:
mysql,sqlserver,oracle;关系型数据库;通用语言SQL;数据是关系表形式;适合关系特别复杂的;支持事务(一组sql操作,要么都成功,要么都失败);
nosql数据库:
MongoDB,Redis,HbaseHadoop;非关系型;不支持sql语法,各有各的语法;数据是键值对形式;不支持事务;
2、Redis
特点:
开源;C语言编写;支持网络;基于内存,也能持久化;key-value数据库;nosql数据库;支持主从模式的数据备份;
应用场景:
做缓存,因为是内存型数据库,数据是放在内存的;存储session;购物车;社交类应用中替代传统数据库;
中文官网:
redis.cn
3、安装
官网下载,tar xzf redisXXX.tar.zip解压;
sudo mv redisXXX /usr/local/redis # 移到指定目录;
cd /usr/local/redis # 进入目录;
sudo make # 生成(C语言写的,先进行编译);
sudo make test # 测试;
如果报错You need tcl 8.5 or newer in order to run the Redis test要先安装tcl;
wget http://downloads.sourceforge.net/tcl/tcl8.6.10-src.tar.gz
sudo tar xzvf tcl8.6.1-src.tar.gz -C /usr/local/
cd /usr/local/tcl8.6.1/unix/
sudo ./configure
sudo make
sudo make install
cd /usr/local/redis/
sudo make test # 再测试;
sudo make intall # 安装;
在/usr/local/bin/下会产生:
redis-server 服务器,
redis-cli 命令行客户端,用来连接服务器;
redis-benchmark 性能测试工具,
redis-check-aof AOF文件修复工具,
redis-check-rdb RDB文件检索工具;数据持久化后的文件就是RDB文件;
4、配置
cd /usr/local/redis
sudo mkdir /etc/redis
sudo cp redis.conf /etc/redis/redis.conf
sudo gedit /etc/redis/redis.conf
修改:
修改daemonize yes # 是否以守护进程运行;
修改logfile "/var/log/redis/redis-server.log" 并创建 /var/log/redis/;
修改dir /var/lib/redis 并创建/var/lib/redis;
其他配置项:
dbfilename dump.rdb数据库文件就保存在dir/dump.rdb
database 16默认有16个数据库,编号0-15;
slaveof 主从复制;
5、启动
redis-server --help查看帮助文档;
sudo redis-server /etc/redis/redis.conf # 启动服务端,路径是配置文件的路径;
ps aux| grep redis # 查看redis服务器进程启动了没;
sudo kill -9
redis-cli # 启动客户端,默认参数redis-cli -h 127.0.0.1 -p 6379;
>ping # 测试,回应PONG;
6、redis数据类型
string是最基本的类型,这里的string是二进制安全的,因此这里的string可以接受任意类型的数据,如JPEG图像、Json对象等;string类型的value最大为512M;
key只能是string类型;
value有string,list,set,zset,hash,但是这些类型的基本类型还是string;
list的元素也是string;
hash类型就是对象,有属性,属性对应的值是string;
set是无序集合,添加元素的顺序和保存的顺序不一致;元素唯一不重复;没有修改操作;
zset是有序集合,元素有double类型的权重score,从小到大排;也是不重复、无修改;
7、redis命令
>select 9 #切换到9号数据库,启动后默认是0号;
>set name qiaofeng # 如果设置的键不存在则添加,已存在则修改;
>get name # 获取键的值;
>set pwd 20 123 # 设置键值pwd:123,过期时间为20秒;
>mset name1 qiaofeng name2 xuzhu name3 duanyu # 一次设置多个键值;
>append name1 qiaobangzhu # 向name1的值追加字符串qiaobangzhu;
>keys n* # 查看以n开头的键,参数可以是正则式;
>keys * # 查看所有键;
>exits name # 判断name键是否存在,返回1/0;
>type name # 查看name的值的类型;
>del name1 name2 # 删除键;
>expire name 10 # 设置name的过期时间为10秒,10秒后此键消失;
>hset user usn qiaofeng pwd qiaofeng # 设置哈希(hashset),哈希跟面向对象中的对象类似,有多个属性:值;键user有属性usn,pwd;
>hmset…… # 和hset一样,按理说hmset的区别是能设置多个属性,但是hset本身就能设置多个属性;
如果hset报错,直接在redis命令行执行config set stop-writes-on-bgsave-error no;
>hkeys user # 返回user的所有属性;
>hget user usn # 返回user的usn属性的值;
>hmget user usn pwd # 返回user的usn和pwd属性;
>hvals user # 返回user的所有属性的值;
>del user # 删除整个hash键
>hdel user usn pwd # 删除user的几个属性;
>lpush chars a b c #设置list类型的键,没有就新建,左侧插入,存储顺序c,b,a;
>lrange chars 0 3 # 返回列表元素[0,3),即第一个到第三个;
>lrange chars 0 -1 # 第一个到最后一个;
>rpush chars d e # 右侧插入,c,b,a,d,e;
>linsert chars before a a- # 在a左边插入'a-';
>linsert chars after a a+ # 在a右边插入'a+';
>lset chars 0 z # 把下标为0的元素改为z;
>lrem chars -2 a # 从列表chars右侧开始删除2个a;list remove;
>lrem chars 1 a #从列表chars左侧开始删除1个a;
>lrem cahrs 0 a # 从列表chars删除全部的a;
>sadd char a b c # 向集合char中添加元素a b c,没有就创建集合;set add;
>smembers char # 获取char集合的所有元素;
>srem char a # 删除集合里的元素a;
>zadd zchar 3 a 4 b 5 c # 向zset中添加元素并指定权重
>zrange zchar 0 -1 # 返回第一个到最后一个元素;
>zrangebyscore zchar 3 5 # 返回权重在[3,5]之间的元素;
>zscore zchar a # 返回元素a的权重;
>zrem zchar a b # 删除元素;
>zremrangebyscore zchar 4 5 # 删除权重在[4,5]的元素;
8、python与redis交互
(pyv1)pip install redis安装模块;
pip freeze查看当前环境安装的py包;
from redis import * # 引入模块;
try:
# 创建StricRedis对象,简写作sr = StrictRedis(),默认的参数就是这个;
sr = StrictRedis(host='localhost', port=6379, db=0)
res = sr.set('name', 'qiaofeng') # 返回一个bool值
res = sr.get('age') # 没有这个键的话也不报错,返回null
res = sr.delete('a1', 'a2') # 返回删除的个数
res = sr.keys() # 默认参数是*,返回所有的键,也可以传正则式,返回匹配的键;
except Exception as e:
print(e)
9、redis数据库存储中文字符
set name ‘乔峰’ 后,以utf-8的编码存储,直接get name得到的是编码\xe4\xb9\x94\xe5\xb3\xb0,解决办法:
命令行中:
以命令redis-cli --raw进入;
python中:
sr.get(‘name’).decode(‘utf-8’);
10、在django项目中用redis代替django-session存储session信息
workon env1fordjango # 进入虚拟环境
pip3 install django # 安装django
pycharm创建django项目:
settings.py中修改配置:
与项目同名的目录/__init__.py中写:(前提是已经pip3 install pymysql了)
与项目同名的目录/url.py中添加include,把booktest这个app的url给include进来:
在booktest应用目录中创建url.py:
(env1fordjango) pip3 install django-redis-sessions # 安装py包,才能在django里使用redis存session
在settings.py中添加配置:
在views.py中写视图函数:
在booktest/url.py(app目录中的url.py)中配置视图函数的url:
启动redis服务并检查:
进入redis客户端,选择2号数据库,现在是空的:
进入项目目录,启动django服务:
结果报错:
解决办法:
项目同名目录/__init__.py中加一句睁着眼睛说瞎话:
再启动一遍:
到浏览器中测试:
到redis中查看,真的有了:
查看session内容,是经过base64编码的:
在线解码查看内容:
11、redis主从配置
主和从可以在一台机器上也可以在不同机器上,如果在不同机器上,要求机器之间可以通信;
改配置文件:(用ifconfig命令查看本机IP地址)
复制一份作为从机的配置文件,并修改:
从机端口不能和主机一样,否则启动不了;replica是复制品的意思;
启动主从服务并检查:
查看主从关系:
主从测试:
主机每写一个数据都会自动备份到从机;
主从的作用:
1)备份,只开一个redis服务的话,这个服务器挂了的话数据就丢了,而创建一个从机就可以自动备份;
2)读写分离,网站数据库的读写比率是10:1,读的时候用从,写的时候用主,提高读写效率,减轻服务器压力;
12、redis集群
就是很多台机器一起对外服务,一台机器承担不了很大量的请求。
集群和分布式的区别:
集群是通过网连接多台计算机共同提供同一个服务;分布式是通过网络连接多台计算机,把一个大服务分成一个个小服务,每个小服务分布到一个计算机上,共同提供服务;总结:集群是干同一件事,分布式是干不同的事;
配置机器1:
创建配置文件:
分别启动三个服务并检查:
配置机器2:
同机器1,创建7003、7004、7005并启动;
创建集群,命令是redis-cli --cluster create,选项--cluster-replicas 1表示每个主机分配一个从机,后面是redis服务的IP:端口:
输入yes
经测试,不管创建时redis服务例程的顺序是怎样的,都会选本机的两个和机器2上的一个作为master,其他做slave;
创建好集群后,这几个节点的集群关系就确定了,不会因为其中一个服务例程结束而拆散集群。
13、解除集群关系(重新设置集群)
首先进入每一个主节点(因为从节点不允许更改数据)客户端,执行以下两句命令:
flushdb # 清除数据库
cluster flushslots # 清除槽(槽是集群存数据的单位)
其次在终端执行以下命令,删除每一个节点:
redis-cli --cluster del-node 192.168.2.109:7001 47271c934fd92fa20fb2cbbc35b850ed8007e141 # 删除一个节点
其中192.168.2.109:7001是当前集群中任意一个节点,因为一个节点就确定一个集群;后面一坨是节点ID,可以进入客户端后执行cluster nodes查看;应注意先删除从节点再删除主节点;节点被删除后,该redis服务进程也一并被杀死。
最后到配置文件中指定的目录中,删除*_node.conf、*.pid、*.aof、*.rdb文件;
完成以后,就可以再次启动所有例程,再次创建集群;
14、redis集群工作原理
redis集群作为一整个数据库,分为16384个槽(slots),平均分配在所有主节点,从节点则作为主节点的备份和复制品;
集群是作为一个整体对外服务的,因此连接集群时,连接任意一个主/从节点都可以,如果连接的是一个从节点,那么这个从节点会变成主节点,他的主节点变成他的从节点,以7002为例:(上文可见7002是7003的从节点,连接到7002后7003变成7002的从节点)
# 连接集群要有 -c 选项
当一个key:value被发送到一个主节点时,该节点会用CRC16(key)%16384算出这个key应该分配到哪个槽;
每个主节点只处理自己负责的槽的数据,如果接收到不属于自己槽的命令,会将正确的节点的地址返回给客户端,客户端会向正确的节点重新发送命令,这个过程称为“转向”:
master挂掉之后,他的slave会代替他的位置;
集群至少有3个主节点,否则创建会失败;
15、redis集群与python交互
pip3 install redis-py-cluster==1.3.6 # 安装py包
为什么安装1.3.6版本:因为redis-py-cluster包和redis包版本不兼容,导致python中导包失败,只有redis-py-cluster1.3.6和redis2.10.6是兼容的,安装redis-py-cluster1.3.6的时候也会自动安装redis2.10.6;
PS:
pip3 install mysqlclient报错:
解决方法:
先执行sudo apt-get install default-libmysqlclient-dev
再执行pip3 install mysqlclient