Redis是一个高性能的key-value数据库
NoSQL(Not only SQL)
- 泛指非关系型数据库
- 不支持SQL语法
- NoSQL存储结构与传统数据库不同,为KV(Key-Value)形式
- NoSQL没有通用语言,每一种NoSQL都有自己的API和语法
- Redis
- Mongodb
- Hbase hadoop
- Cassandra hadoop
NoSQL与SQL比较
- 使用场景不同
- SQL适用于数据结构比较复杂的场景
- NoSQL反之
事务
特性的支持不同- SQL对事务的支持非常完善
- NoSQL基本不支持事务
Redis简介
- Redis开源、使用ANSI C语言编写
- 可基于内存,也可持久化的日志型
- Key-Value数据库,支持多种语言API
Redis优势
- 性能极高,理论读速度110000次/s,写速度81000次/s
- 丰富的数据类型,支持二进制案例的Strings、Lists、Hashes、Sets及Ordered Sets数据类型操作
- 原子-Redis的所有操作都素hi原子级的
- …….
Redis应用场景
- 用来做缓存——Redis的所有数据是放在内存中的(内存数据库)
- 可以在某些特定应用场景下替代传统数据库一- 比如吐交类的应用
- 在一些大型系统中,巧妙地实现一些特定的功能: session共享、购物车
- ……
Redis安装
下载、解压wget http://download.redis.io/releases/redis-6.0.6.tar.gz
tar -zxvf redis-6.0.6.tar.gz
移动到安装目录下,、编译Redissudo mv ./redis-6.0.6 /usr/local/redis
sudo make
测试安装成功(时间会很长)make test
将redis的命令安装到/usr/local/bin
中,方便直接运行sudo make install
安装成功后,进入/usr/local/bin
查看cd /usr/local/bin
ll
- redis-server redis服务器
- redis-ci redis命令行客户端
- redis-benchmark redis性能测试工具
- redis. .check -aof AOF文件修复工具
- redis-check-rdb RDB文件检索工具
启动
服务端
可以先查看redis服务端是否启动ps aux | grep redis
先启动服务端redis-server
查看命令帮助redis-server –help
客户端
再启动客户端redis-cli
查看帮助redis-cli –help
常见配置项
- daemonize:是否守护进程(以服务形式运行),一般设为yes
- pidfile:PID文件所在位置
- port:6379
- bind:绑定IP,如果需要远程访问,可将次行注释,或绑定公网IP
- logfile:日志文件位置
- databases:16 (数据库只有16个数据库)
- dbfilename:将内存中的数据备份为文件,防止断电清空内存数据丢失
设置密码config set requirepass 123456
输入密码redis-cli
auth 123456
远程配置访问需要将bind注释掉
Redis使用
客户端
运行测试命令
ping
切换数据库
数据库没有名称,默认16个,通过0-15标识,连接Redis后默认使用第一个数据库select 10
值的类型
- 字符丰string
- 哈帮hash
- 列表list
- 集合set
- 有序集合zset
数据操作
- 获取
- 保存
- 修改
- 删除
Redis数据操作
String类型
增加数据
查看命令帮助help setset name xiaozhiset age 22
设置key过期
可以用于实现验证码的功能,自动销毁
SETEX key seconds value summary: Set the value and expiration of a key since: 2.0.0 group: string
setex captcha 60 123456
查看key有效期
ttl captcha
- 没有设置时间为-1
- 过期为-2
增加多个数据
help mset
m是multiple的意思,多个
MSET key value [key value …] summary: Set multiple keys to multiple values since: 1.0.1 group: string
mset address dongbei age 16
追加字符串数据
APPEND key value summary: Append a value to a key since: 2.0.0 group: string
set name xiaozhiappend name best
那么最终name的value为xiaozhibest
获取数据
help getget nameget age
获取多个数据
对应于mset
MGET key [key …] summary: Get the values of all the given keys since: 1.0.0 group: string
mget address age
更新数据
set name newname
直接覆盖原来的数据
删除数据
del name
Key
查看所有key
keys *
查看a开头的所有key
keys a*
查看key是否存在
查看name是否存在exists name
存在返回1,不存在返回0
查看指定key的value类型
查看key为name的value类型type name
设置key过期时间
key为name,3s过期expire name 3
Hash类型
hash用于存储对象,对象的值均为Key-value,value的值为string
添加数据
假设我们有这样一个对象class person:{
name=xiaozhi,
age=22,
address=dongbei
}
那么使用hset命令添加数据
HSET key field value [field value …] summary: Set the string value of a hash field since: 2.0.0 group: hash
老版本redis中只能给key设置一个hash类型的value值
参照官方文档
As per Redis 4.0.0, HMSET is considered deprecated. Please use HSET in new code. 根据Redis 4.0.0,HMSET被视为已弃用。请在新代码中使用HSET。
新版本redis,使用hset一样可以设置多个数据hset person name xiaozhi address dongbei age 22
获取数据
获取hash单个key数据
HGET key field summary: Get the value of a hash field since: 2.0.0 group: hash
hget person name
获取多个数据
HMGET key field [field …]
summary: Get the values of all the given hash fields since: 2.0.0 group: hash
hmget person name address age
获取所有hash值
包括key和value
HGETALL key summary: Get all the fields and values in a hash since: 2.0.0 group: hash
hgetall person
获取所有Key
HKEYS key summary: Get all the fields in a hash since: 2.0.0 group: hash
hkeys person
获取所有值
HVALS key summary: Get all the values in a hash since: 2.0.0 group: hash
hvals person
删除数据
删除hash的单个value
删除person中的namehdel person name
删除整个hash值
del person
更新数据
直接hmset修改hmset person name xiaozhi address dongbei age 22
修改后hmset person name zhixiao address liaoning age 52
list类型
列表就是,一个key包含多个值
- 值类型均为string
- 插入顺序排序
增加数据
左插入
先向class_1添加三个名字数据lpush class_1 zhangsan
lpush class_1 lisi
lpush class_1 wangwu
因为是左插入,所以顺序为1) “wangwu”
2) “lisi”
3) “zhangsan”
右插入
rpush class_1 2222
顺序为:1) “wangwu”
2) “lisi”
3) “zhangsan”
4) “2222”
获取数据
LRANGE key start stop summary: Get a range of elements from a list since: 1.0.0 group: list
0表示第一个元素
-1表示最后一个元素(负索引)
所以获取全部数据可以写为lrange class_1 0 -1
获取第1~3个数据lrange class_1 0 2
移除数据
- 将列表中前count 次出现的值为value 的元索移除
- count> 0:从头往尾移除
- count < 0:以尾往头移除
- count= 0;移除所有
当数据为1) “2222”
2) “wangwu”
3) “lisi”
4) “zhangsan”
5) “2222”
删除第一个和最后一个元素,则为lrem class_1 1lrem class_1 -1
更新数据
第一个数据的索引为0lset class_0 0 gengxin
插入数据
LINSERT key BEFORE|AFTER pivot element summary: Insert an element before or after another element in a list since: 2.2.0 group: list
将列表中值为lisi的元素前插入一个abcde
当前数据为:1) “2222”
2) “wangwu”
3) “lisi”
4) “zhangsan”
5) “2222”linsert class_1 before lisi abcde
插入后1) “2222”
2) “wangwu”
3) “abcde”
4) “lisi”
5) “zhangsan”
6) “2222”
set类型
- 无序
- 元素都是string类型
- 元素唯一,不重复
- 对于聚合,没有修改操作
添加数据
sadd stu_1 zhangsan lisi
获取数据
查看集合里的所有成员smembers stu_1
移除数据
srem stu_1 lisi
zset类型
- sorted set 有序集合
- 元素为string类型
- 元素唯一、不重复
- 每个元素都会绑定一个double类型的score,表示权重,通过权重将元素从小到大排列
- 没有修改操作
添加数据
ZADD key [NX|XX] [CH] [INCR] score member [score member …] summary: Add one or more members to a sorted set, or update its score if it already exists since: 1.2.0 group: sorted_set
zadd ordered_set 100 zhangsan 99 lisi 50 wangwu 20 xiaozhi
数字表示权重,也就是分数,成员表示人名
获取数据
获取所有元素
zrange ordered_set 0 -11) “xiaozhi”
2) “wangwu”
3) “lisi”
4) “zhangsan”
从小到大
获取指定范围元素
返回权重在0和100之间的成员zrangebyscore ordered_set 0 100
获取成员的权重
zscore ordered_set xiaozhi
修改数据
因为吧…..set的元素是唯一的,当插入与集合内元素相同的成员时,会用新的成员替换旧的成员zadd ordered_set 100 xiaozhi
删除数据
按照成员删除
zrem ordered_set lisi wangwu
按指定权重范围删除
zremrangebyscore ordered_set 80 100
包括80和100,闭区间
删除权重在最大最小之间的元素zremrangebyscore ordered_set min max
Python使用Redis
安装Redis
pip install redis
参照开发文档进行程序编写
主从服务器搭建
主从概念
一个主服务器master包含多个从服务器slave,1个slave又可以分为多个slave
- master用来写数据,slave用来读数据(经统计:网站的读写比率是10:1)
- 通过主从配置可以实现读写分离
- 主从服务器通过日志实现数据同步
主服务器配置
首先改主服务器绑定IP
假设主服务器IP:192.168.33.30
从服务器IP:192.168.33.25bind 192.168.33.30 127.0.0.1
重启Redissodo service redis stop
redis-server
从服务器配置
可以从主服务器cp一份配置,进行修改cp /usr/local/redis/redis.conf ./slave.conf
vim slave.conf
设置绑定IPbind 192.168.33.25 127.0.0.1
设置主服务器IP和端口号
(同一设备需要设置不同端口号,模拟主从效果,不同设备可以使用同一IP)slaveof 192.168.33.30 6379
port 6378
重启Redisredis-server slave.conf
查看主从关系redis-cli -h 192.168.33.30 info replication
分布式集群搭建
集群是为了解决请求量过大时,主服务崩溃的情况
分布式可以分为两个层面
- 软件层面:一个主机开启多个服务
- 硬件层面:多个主机多个服务
集群配置
配置内容port 7000
bind 192.168.33.30 # 服务节点IP
daemonize yes # 守护进程
pidfile 7000.pid #PID文件
cluster-enabled yes # 集群使能
cluster-config-file 7000_node.conf # 集群配置文件
cluster-node-timeout 15000 # 集群超时时间
appendonly yes # 增量备份port 7001
bind 192.168.33.30 # 服务节点IP
daemonize yes # 守护进程
pidfile 7001.pid #PID文件
cluster-enabled yes # 集群使能
cluster-config-file 7001_node.conf # 集群配置文件
cluster-node-timeout 15000 # 集群超时时间
appendonly yes # 增量备份
……..
安装rubysudo apt-get install ruby
复制redis-trib.rb到/usr/bin/下sudo cp /usr/local/redis/src/redis-trib.rb /usr/bin/
运行所有节点redis-server 7000.conf
redis-server 7001.conf
…..
使用命令创建集群redis-trib.rb create –replicas 1 192.168.33.30:7000 192.168.33.30:7001
1表示1主1从结构,如果有6台主机,则有三个节点(或者一台主机6个服务,也是3个节点)
选yes确认创建集群
集群中的每个节点都是平等的,每个数据库都保存集群的状态和各自的数据。每个节点都和其他节点有连接
CRC16算法
- Redis集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做哈希檀(hash slot)的方式 来分配的
- redis cluster默认分配了16384 个slot,当我们set-个key时,会用CRC16算法来取模得到所属的slot,然后将这个key分到哈希梧区间的节点上,具体算法就是: CRC16(key) % 16384。所以我们在测试的时候看到set和get的时候,直接跳转到了7000端口的节点
- Redis集群会把数据存在一个master节点,然后在这个master和其对应的salve之间进行数据同步。当读取数据时,也根据一致性哈希算法到对应的master节点获取数据。只有当一个master挂掉之后,才会自动一个对应的salve节点,充当master
- 需要注意的是:必须要3个或以上的主节点,否则在创建集群时会失败,并且当存活的主节点数小于总 节点数的一半时,整个集群就无法提供服务了
使用Python操作集群
安装相关库pip3 install redis-py-cluster
编写相关代码