一、Redis
1.NoSQL的介绍
这是一类新出现的数据库(not only sql)
- 泛指非关系型数据库
- 不支持SQL语法
- 存储结构跟传统关系型数据库中的那种关系表完全不同,nosql中存储的数据都是KV形式
- NoSQL的世界中没有一种通用的语言,每种nosql数据库都有自己的API和语法,以及擅长的业务场景
- NoSQL中的产品种类也相当多:Redis、Mongodb、Hbase hadoop、Cassandra hadoop
2.NoSQL和SQL数据库的比较:
- 使用场景不同:SQL数据库适合用于关系特别负责的数据查询场景,NoSQL反之
- 事务特性的支持:SQL对事务的支持非常完善,而nosql基本不支持事务
- 两者在不断的取长补短,呈现融合趋势
3.Redis的介绍
- Redis是一个开源的使用的ANSIC语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value型数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作有VMware主持。从2013年5月起,Redis的开发由Pivotal赞助。
- Redis是NoSQL技术阵营中的一员,它通过多种键值数据类型来使用不同的场景下的存储需求,借助一些高级层的接口使用其可以胜任,如缓存、队列系统的不同角色
4.Rredis的特性
- Redis与其他Key-Value缓存产品有以下三个特点:
- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用
- Redis不仅支持简单的Key-Value类型的数据,同时还提供String、hash、list、set、zset等数据结构的存储
- Redis支持数据的备份,即master-slave模式的数据备份
5.Redis的优势
- 性能极高,Redis的读速度是110000次/s,写的速度是81000次/s
- 丰富的数据类型,支持二进制案例的Strings、Lists、Hashes、Sets及Ordered Sets数据类型操作
- 原子性,Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行
- 丰富的特性,Redis还支持publish/subscribe,通知,key过期等特性
6.Redis的应用场景
- 用来做缓存(ehcache/memcached)——redis的所有数据都是放在内存中的(内存数据库)
- 可以在某些特定应用场景下替代传统数据库——比如社交类的应用
- 在一些大型系统中,巧妙的实现一些特定的功能:session共享、购物车等
- 只要你有丰富的想象力,Redis可以给你无限的惊喜…
二、Redis的核心配置选项
1.Redis的配置信息在 /etc/redis/redis.conf下
2.查看
- sudo vi /etc/redis/redis.conf
3.绑定ip:如果需要远程访问,可以将慈航注释,或者绑定一个真实ip
- bind 127.0.0.1
4.端口号:默认为6379
- port 6379
5.是否设置为守护进程运行
- 如果以守护进程运行,则不会存在命令行阻塞,类似于服务
- 如果以非守护进程运行,则当前终端会被阻塞
- 设置为yes表示守护进程,设置为no为非守护进程
- 推荐设置为yes
- daemonize yes
6.数据文件
- dbfilename dump.rdb
7.数据文件存储路径
- dir /var/lib/redis
8.日志文件
- logfile “/var/log/redis/redis-server.log”
9.数据库,redis中的数据库默认有16个
- database 16
10.主从复制,类似于双机备份
- slaveof
三、服务端和客户端的命令
1.开启客户端和服务端有两种方式:
- 默认方式
- 配置文件方式
2.默认方式:
- 服务端命令:redis-server
- 客户端命令:redis-cli
3.配置文件方式:
- 服务端命令:sudo redis-server /etc/redis/redis.conf
- 客户端命令:redis-cli -h 服务端ip地址 -p 服务端端口号
- 推荐使用配置文件方式
4.使用help命令查看帮助文档
- redis-server --help 查看服务端帮助文档
- redis-cli --help 查看客户端帮助文档
5.个人习惯常用命令:
- ps aux | grep redis-server 查看redis服务器的进程
- sudo kill -9 pid 杀死redis服务器进程
- sudo redis-server /etc/redis/redis.conf 指定加载的配置文件
6.切换数据库
- 数据库没有名称,默认有16个,通过0-15来表示,连接redis默认选择第一个数据库0
- select 10 则是选择第10个数据库
四、Redis五种数据类型及操作
1.Redis的数据结构
- redis是Key-Value的数据结构,每条数据都是一个键值对
- 键的类型是字符串,且不能重复
- 值的数据类型分为五种:
- 字符串string
- 哈希hash
- 列表list
- 集合set
- 有序集合zset
2.数据操作行为无非就是增删改查。
3.sring类型
- 字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制的,这便意味着该类型可以接受任何个数的数据,如JPEG图像数据或Json对象描述信息等。在Redis中字符串类型的Value最多可以容纳的数据长度是512M
(1)增加操作
- 设置键值 set
格式:
set key value
例:设置键为name的值为csdn的数据
set name csdn
- 设置键值及过期时间 setex
格式:
setex key seconds value
例:
设置键为name的值为csdn的过期时间为5秒
setex name 5 csdn
- 设置多个键值 mset
格式:
mset key1 value1 key2 value2...
例:设置键为a1的值为python,设置键为a2的值为redis,设置键为a3的值为ok
mset a1 python a2 redis a3 ok
(2)删除操作
- 删除键
格式:
del key
例:删除键a1
del a1
(3)修改操作
- 修改键值 set
格式:
set key newvalue
例:
修改a2的键值为newredis
set a2 newredis
(4)查询操作
- 查询 get、mget
# 根据键获取值,如果键不存在则会返回nil
格式:
get key
例:获取键为a3的值
get a3
# 获取多个键的值
格式:
mget key1 key2 key3...
- 在末尾追加值 append
格式:
append key value
例:在键a3中追加值hello
append a3 hello
4.hash类型
- hash类型用于存储对象,对象的结构为对象 属性 值
- 值的类型为string
(1)增加操作
- 设置单个属性 hset
格式:
hset key field value
例:设置键person的属性name为csdn
hset person name csdn
- 设置多个属性 hmset
格式:
hmset key filed1 value1 filed2 value2...
例:设置键user的属性name为wtt,属性age为22
hmset user name wtt age 22
(2)删除操作
- 删除整个hash键及值,使用Del命令
- 删除属性,属性对应的值也会被删除
格式:
hdel key filed1 filed2...
例:删除键user的属性name
hdel user name
(3)修改操作
- 修改属性值 hset
格式:
hset key filed newvalue
例:修改user中的属性age的值为18
hset user age 18
(4)查询操作
- 获取一个属性的值 hget
格式:
hget key filed
例:获取user中的属性age的值
hget user age
- 获取多个属性的值 hmset
格式:
hmget key filed1 filed2 filed3...
例:获取user中的name,age,address属性的值
hmget user name age address
- 获取所有属性的值 hvals
格式:
hvals key
例:获取user中所有属性的值
havls user
- 获取指定键的所有属性 hkeys
格式:
hkeys key
例:获取user中的所有属性
hkeys user
- 获取指定键的所有属性和值 hgetall
格式:
hgetall key
例:获取user中的所有属性和值
hgetall user
5.list类型
- 列表的元素类型为string
- 按照插入的顺序排序
(1)增加操作
- 增加数据lpush rpush
格式:
lpush key value1 value2...
例:从键为a1的列表左侧加入数据1,2,3,4
lpush a1 1 2 3 4
查询结果为 4 3 2 1 因为lpush是从左侧插入数据
如果想要按照输入的顺序进行输出可以使用rpush
格式:
rpush key value1 value2...
例:从键为a2的列表右侧加入数据 1 2 3 4
rpush a2 1 2 3 4
查询结果为 1 2 3 4
(2)删除操作
- 删除指定元素 lrem
格式:
lrem key count value
例:从a2列表右侧开始删除3个1
lrem a2 -3 1
count说明:是将列表前count次出现的值为value的元素删除
count > 0 表示从头到为删除
count < 0 表示从尾到头删除
count = 0 表示全部删除
(3)修改操作
- 修改设置指定索引位置的元素值lset
格式:
lset key index value
例:
修改键为a2的列表中的下标为1的元素值为A
lset a2 1 A
index 说明: 索引从左侧开始,第一个元素为0
索引可以是负数,表示从尾部开始技术,如-1表示最后一个元素
(4)查询操作
- 获取列表里指定范围内的元素lrange
格式:
lrange key start stop
例:获取键为a2的列表的所有元素
lrange a2 0 -1
start、stop说明:start表示开始的下标索引、stop表示结束的下标索引。都是闭区间
(5)插入操作
- 在指定元素的前或后插入新元素linsert
格式:
linsert key before/after 现有元素 新元素
例:在aa列表中的3元素前插入新元素A
linsert aa before 3 A
(6)截取删除操作
- 截取在[start stop]区间内的元素,区间外的元素全部删除 ltrim
格式:
ltrim key start stop
例:把aa列表中的下标为3到5之间的元素取出来,其他元素全部删除
ltrim aa 3 5
6.set类型
- 无序集合,元素的类型为string类型
- 元素具有唯一性,不重复
- 没有修改操作
(1)增加操作
- 添加元素 sadd
格式:
sadd key value1 value2 ...
例:项键a33的集合中添加元素zhangsan、lisi、wangwu
sadd a33 zhangsan lisi wangwu
(2)删除操作
- 删除元素 srem
格式:
srem key value
例:删除键a33集合中的元素wangwu
srem a33 wangwu
(3)查询操作
- 获取所有元素 smembers
格式:
smembers key
例:获取键a33集合中的所有元素
smembers a33
7.zset类型
- 有序集合,元素为string类型
- 元素具有唯一性,不重复
- 每个元素都会关联一个double类型的score,表示权重,通过权重将元素从小到大排序
- 没有修改操作
(1)增加操作
- 添加元素 zdd
格式:
zadd key score1 value1 score2 value2...
例:向键a4集合中添加元素zhangsan、lisi、wangwu、laoliu,权重分别为3,5,2,10
zadd a4 3 zhangsan 5 lisi 2 wangwu 10 laoliu
(2)删除操作
- 删除元素 zrem , zremrangebyscore
格式1:根据元素删除
zrem key value1 value2...
例1:删除a4集合中的zhangsan
zrem a4 zhangsan
格式2:根据权重范围删除
zremrangebyscore key min max
例2:删除a4集合中权限在5-8之间的元素
zremrangebyscrore a4 5 8
(3)查询操作
- 返回指定范围内的元素
- 根据权重范围返回值
- 根据元素查权重
格式1:返回指定范围内的元素
zrange key start stop
例1:查询a4集合中的所有元素
zrange a4 0 -1
格式2:根据权重范围返回值
zrangebyscore key min max
例2:查询a4集合中权重值在1-5之间的元素
zrangebyscore a4 1 5
格式3:获取元素的权重值
zscore key value1
例3:获取a4集合中wangwu的权重值
zscore a4 wangwu
7.键命令基本操作
- 对键的一些基本操作
- 增删改查等
(1)查找操作
- 查找键,参数支持正则表达式 keys
格式:
keys pattern
例1:查看所有键:
keys *
例2:查看名称中a开头的键
keys a*
(2)删除操作
- 删除键及其对应的值 del
格式:
del key1 key2...
例:删除键a,b,c
del a b c
(3)判断键是否存在
- 如果键存在返回1,不存在返回0 exists
格式:
exists key
例:判断键a1是否存在
exists a1
(4)查看键类型
- 查看键的值类型,为redis支持的5种类型之一 type
格式:
type key
例:查看a1键的值类型
type a1
(5)设置键过期时间
- 以秒为单位,没有指定过期时间则一直存在,直到使用DEL移除。expire
格式:
expire key seconds
例:设置键a1的过期时间为10秒
expire a1 10
(6)查看键有效时间
- 以秒为单位,查看键的剩余时间。ttl
格式:
ttl key
例:查询键a1的剩余时间
ttl a1
六、Python与Redis的交互
1.安装配置环境
安装Redis的方式有三种
- 第一种:联网安装包Redis
pip3 install redis - 第二种:联网安装包redis
easy_install redis - 第三种:到中文官网-客户端下载redis包的源码,使用源码安装
一步步执行 wget https://github.com/andymccurdy/redis-py/archive/master.zipunzip master.zip
cd redis-py-master
sudo python setup.py install
2.在pycharm中调用模块
- 引入模块
from redis import StrictRedis - 这个模块中提供了SrictRedis对象,用于连接redis服务器,并按照不同类型提供了不同方法,进行交互操作
3.StricptRedis对象方法
- 通过init创建对象,指定参数host、port与指定的服务器端口连接,host默认为localhost,port默认为6379,db默认为0
str = SrtictRedis(host=‘localhost’,port=6379,db=0) - 简写
str = StrictRedis() - 根据不同的类型,拥有不同的实例方法可以调用,与前面学的redis命令对应,方法需要的参数与命令的参数一致
4.使用SrtitctRedis对象对string类型的数据进行增删改查
准备:
- 安装pip3 install redis
- 在pycharm中新建一个py文件
- 代码如下:
import redis
if __name__ == '__main__':
try:
# 创建StrictRedis对象,与redis服务器建立连接
str = StrictRedis()
except Exception as e:
print(e)
String的增删改查操作
- 编写代码如下
import redis
if __name__ == '__main__':
try:
# 创建StrictRedis对象,与redis服务器建立连接
str = StrictRedis()
# 设置键name的值
ret1 = str.set("name","WangTaoTao")
# 获取键name的值
ret2 = str.get("name")
# 在控制台输出name的值
print(ret2)
# 更改键name的值
ret3 = str.set("name","New__WangTaoTao")
# 在控制输出更改后的name的值
print(ret3)
# 删除键name的值 注意:这里面的set删除需要用delete
ret4 = str.delete("name")
except Exception as e:
print(e)
说明:其他数据类型与此类似,不一一介绍。
七、搭建主从
1.主从概念
- 一个主(master)可以拥有多个从(slave),一个slave又可以拥有多个slave,如此下去,形成了强大的多级服务器集群结构
- master用来写数据,slave用来读数据
- 通过主从配置可以实现读写分离
- master和slave都是一个redis实例(redis服务)
2.配置主
- 查看当前主机的ip地址
ifconfig - 修改 /etc/redis/redis.conf配置文件
sudo vi redis.conf
bind 当前主机ip地址
3.配置从
- 复制 /etc/redis/redis.conf文件
sudo cp redis.conf ./slave.conf - 修改slave.conf文件
sudo vi slave.conf - 修改内容
bind 主机ip地址
slaveof 主机ip地址 主机端口号
port 从端端口号(注意:这个端口号不能和主机端口号相同)
4.开启主从服务
- 开启主服务
sudo redis-server redis.conf - 开启从服务
sudo redis-server slave.conf - 查看主从关系
redis-cli -h 主机ip地址 info Replication
5.校验主从读写
- 在master和slave分别执行info命令,查看输出信息
首先进入主
redis-cli - h 主机ip地址 -p 主端口号 - 然后进入从
redis-cli - h主ip地址 -p 从端端口号 - 然后在主端写数据
set name wtt - 然后在从端读数据
get name
注意:主端能写能读,但是从端只能读数据。
八、搭建集群
- 为什么要有集群?
- 之前我们了解了主从的概念,一个主可以多从,但是如果同时的访问量过大,主服务肯定会挂掉,如果主服务挂掉了,那么其他的从服务也就没有了存在的意义。
- 大公司一般都有很多的服务器(华北地区、华东地区、东北地区等等)
- 什么是集群
- 集群是一组相互独立的、通过告诉网络互联的计算机,它们构成了一个组,并且以单一系统的模式加以管理。一个客户端与集群相互作用时,集群像是一个独立的服务器。集群配置是用于提高可用性和可缩放性。
- 当请求到来首先由负载均衡服务器处理,然后把请求转发到另外的一台服务器上。
- Redis集群
- 分类
- 软件层面
- 硬件层面
- 软件层面:只有一台电脑,在这一台电脑上启动了多个redis服务
- 硬件层面:存在多台实体的计算机,每台计算机上面都启动了一个或者多个redis服务
4.搭建集群
- 1.配置3个主
- 2.配置3个从
- 3.启动6个服务node节点
- 4.创建集群
(1)配置3个主的配置文件
在桌面创建一个conf文件夹,然后新建6个conf文件,并分别更改内容
2.1 cd ~/Desktop
2.2 mkdir conf
2.3 cd conf
2.4 touch 7001.conf 编辑内容如下
port 7001
bind 192.168.144.125
daemonize yes
pidfile 7001.pid
cluster-enabled yes
cluster-config-file 7001_node.conf
cluster-node-timeout 15000
appendonly yes
2.5 复制7001.conf为7002.conf 7003.conf
2.6 三个文件的配置区别在于port、pidfile、cluster-config-file三项均改为与文件的名字相同
(2)配置三个从文件
3.1 复制7001.conf 为7004.conf,7005.conf,7006.conf
3.2 三个⽂件的配置区别在port、pidfile、cluster-config-file三项均修改为文件的名字相同
(3)启动6个服务的node节点
redis-server 7001.conf
redis-server 7002.conf
redis-server 7003.conf
redis-server 7004.conf
redis-server 7005.conf
redis-server 7006.conf
- 查看进程
ps aux | grep redis-server
(4)创建集群
- redis的安装包里包含了redis-trib.rb ,用于创建集群
- 将命令复制,这样可以在任何目录下调用此命令
sudo cp /usr/share/doc/redis-tools/examples/redis-trib.rb /usr/local/bin/
- 安装ruby环境,因为redis-trib.rb是用ruby开发的
sudo apt-get install ruby
- 运行如下命令创建集群
redis-trib.rb create --replicas 1 192.168.144.125:7001 192.168.144.125:7002 192.168.144.125:7003 192.168.144.125:7004 192.168.144.125:7005 192.168.144.125:7006
提示[OK]All,表示集群搭建成功
- 执⾏上⾯这个指令在某些机器上可能会报错,主要原因是由于安装的 ruby 不是最 新版本!
- 天朝的防⽕墙导致⽆法下载最新版本,所以需要设置 gem 的源
- 解决办法如下
-- 先查看⾃⼰的 gem 源是什么地址
gem source -l -- 如果是https://rubygems.org/ 就需要更换
-- 更换指令为
gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/
-- 通过 gem 安装 redis 的相关依赖
sudo gem install redis
-- 然后重新执⾏指令
(5)数据验证
- 当前搭建的主服务器为7001、7002、7003,对应的从服务器是7004、7005、7006
- 先连接上7002 ,加参数 -c 表示连接到集群
- redis-cli -h 192.168.144.125 -c -p 7002
- 写数据
- set a 1
- 然后会自动跳换到7002服务器,并写入数据成功。
**说明:必须要3个或以上的主节点,否则在创建集群时会失败,并且当存活的主节点数小于总结点数的一半时,整个集群就无法提供服务了。
5.将搭建好的集群与Python进行交互
- 安装包
- pip3 install redis-py-cluster
- 代码如下
# 导入包
import rediscluster
if __name__ == '__main__':
try:
# 构建所有节点,redis会使用CRC16算法,将键和值写到某个节点上。
nodes_list = [
{'host':'192.168.144.125','port':'7001'},
{'host':'192.168.144.125','port':'7002'},
{'host':'192.168.144.125','port':'7003'},
{'host':'192.168.144.125','port':'7004'},
{'host':'192.168.144.125','port':'7005'},
{'host':'192.168.144.125','port':'7006'},
]
# 构建StrictRedisCluster对象
str = StrictRedisCluster(startup_nodes = nodes_list, decode_responses = True)
# 设置键为a ,值为 1的数据
ret1 = str.set("a",1)
print(ret1)
# 获取键a的值
ret2 = str.get("a")
print(ret2)
except Exception as e:
print(e)