一、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.zip
unzip 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)