Redis学习笔记
NoSql
非关系型数据库,随着互联网的发展传统的关系型数据库针对于超大规模和高并发的网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题,包括超大规模数据的存储。
这种类型的数据的数据在存储的时候不需要固定的模式,无需多余的操作就可以实现横向扩展并且在数据之间没有关系
RDBMS VS NoSQL
RDBMS
- 高度组织化结构化数据
- 结构化查询语言(SQL)
- 数据和关系都存储在单独的表中。
- 数据操纵语言,数据定义语言
- 严格的一致性
- 基础事务
NOSQL
- 代表着不仅仅是SQL
- 没有声明性查询语言
- 没有预定义的模式
- 键 - 值对存储,列存储,文档存储,图形数据库
- 最终一致性,而非ACID属性
Redis其实就是KV+Cache+Persistence
当下基本都是SQL+NOSQL进行连用的
Redis入门介绍
Redis是完全开源免费的,使用C语言进行编写的是一个高性能的(Key/value)分布式内存数据库,基于内存运行并且支持持久化的NOSQL数据库,是当下最热门的NOSQL数据库之一,因为也被称为数据结构服务器
对于Redis的安装这里建议是通过docker安装,所以需要了解Dokcer的基本操作这里就不进行具体描述了
在启动Redis之后杂项基础知识
- select 切换数据库
- Dbsize 查看当前数据库的Key的数量
- Flushdb 清空当前库
- 统一密码管理 16个库是同样的密码 要么都OK要么一个也连接不上
- 默认端口是679
Redis数据类型
- String (字符串)
- Hash(哈希类似于Java里面的Map)
- List(列表)
- Set(集合)
- Zset(sorted set:有序集合)
String是redis最基本的类型 String类型是二进制安全的 redis的String可以包含任何数据 一个Redis字符串最多可以是512M
Hash是一个键值对集合,特别适合用于存储对象 类似Map<String,Object>
List是简单的字符串列表 按照插入的顺序进行排序 本质是一个链表
Set 是String类型的无序集合 通过HashTable实现的
zset(sorted set:有序集合) 与set一样是String类型元素的集合,且不允许重复的成员不同的是每个元素都会关联一个double类型的分数
Redis命令大全http://redisdoc.com/
Redis常用的Key操作
- Keys *查询所有的
- exists key 的名字判断某一个key是否存在
- move key db -->将当前数据库的key转移到指定的数据库db里面
- expire key 为Key设置过期的时间
- ttl key查看还有多少秒过期 -1永远不会过期
- type key 查看你的Key是什么类型
String类型操作
-
set key value设置值—get key 获取值—getset key value 将给定的值设置为value 并返回key的旧值(old value)先Get后Set
-
mget k1 [k2…]获取多个key值 mset k1 [k2 …]同时设置多个值 msetnx同时设置多个键值对
-
setex key seconds value 设置值的同时 设置key的过期时间
-
setnx key value 只有key不存在的时候才会设置Key的值
-
strlen key获取key的长度
-
incr/decr/incrby/decrby 一定要是数字才能够进行加减操作
-
APPEND key value 如果key存在追加 不存在设置
-
getrange获取指定区间范围内的值,类似between…and的关系 指的是位置0—>?
-
setrange设置指定区间范围内的值,格式是setrange key值 具体值
set k1 abcd123--> setrange k1 1 xxx==>axxx123
List类型操作
- llen key 获取长度–>lpush key value将值插入到列表的头部—>lpushx key value将一个或者多个值插入到已经存在的列表的头部–>rpush key value将值添加到列表表尾部
- lrange key start stop 获取指定范围的元素
- lindex 按照索引下标获取元素 llen key 获取长度
- lrem key 删除N个value
它是一个字符串链表,left、right都可以插入添加;如果键不存在,创建新的链表;如果键已存在,新增内容;如果值全移除,对应的键也就消失了。链表的操作无论是头和尾效率都极高,但假如是对中间元素进行操作,效率就很惨淡了
Set类型
- sdd key value
- smembers key 获取当前key的所有数据
- scard 获取集合里面元素的个数
- srem key value删除集合中元素
- srandmember key某个整数(随机出几个数)
- spop key随机出栈
- 差集 sdiff k1 k2 在k1里面不在k2里面
- 交集 sinter sinter k1 k2
- 并集 sunion k1 k2
Hash类型
K-V键值对保持不变 只不过这里的V也是一个K-V键值对
-
hset/hget/hmset/hmget/hgetall/hdel 添加 获取 设置多个 得到多个 得到全部 删除
例如 hset h1 a1 1-->hget h1 a1 hmset h2 a2 2 a3 3 ==>hmget h2 a2 a3/hgetall h2
-
hlen 获取长度
-
hexists key 在key里面的某个值的key
-
hkeys/hvals 获取所有的key值和val值
-
hsetnx 不存在复制 存在的话无效
Zset有序集合
- 是在Set的基础上加一个score值
- 这里不在讲述 使用较少 想要了解查看命令地址http://redisdoc.com/
Redis配置文件的常见配置
- port 6379 对应的是设置端口
- bind 127.0.0.1 绑定主机地址
- timeout 300 客户端闲置多长时间关闭
- loglevel verbose 指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose
Redis持久化
RDB
- 在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里
- 如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方
式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。 - RDB保存的是dunp.rdp文件
AOF
- 也是用日志的形式进行存储 但是对于每一次操作都会进行存储
- 保存的位置是appendonly.aof
两种进行对比
-
RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储
-
AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些
-
命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大
-
只做缓存:如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式
Redis事务
可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞
常用命令
- discard 取消事务
- exec 执行所有的事务
- multi 标记事务快的开始
- unwatch 取消watch命令对所有的key进行监视
- watch k1 [k2…]监视一个或者多个Key ,如果事务在执行之前key被其他的命令所该案 那么事务会被打断
正常的执行
- multi -->set k1 1–> get k1 -->exec
放弃事务
- multi—>set name 123—>discard
在执行过程中 如果是命令书写错误 那么就会全部出错 如果是运行的时候出错 那么只会显示这一条错误
Watch监控
悲观锁/乐观锁
- 悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁
- 乐观锁: 每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,但是会产生ABA问题 所以提交的版本必须大于记录当前的版本才能执行更新
在监控的过程中一旦出现了加塞 操作就会失败 只有重新监控才可以
unwatch取消监控
当我们执行了exec之前加的监控锁都会被取消掉
总结:
- Watch指令,类似乐观锁,事务提交时,如果Key的值已被别的客户端改变,比如某个list已被别的客户端push/pop过了,整个事务队列都不会被执行
- 通过WATCH命令在事务执行之前监控了多个Keys,倘若在WATCH之后有任何Key的值发生了变化,EXEC命令执行的事务都将被放弃,同时返回Nullmulti-bulk应答以通知调用者事务执行失败
事务执行的三个阶段
- 开启 以MULTI开始一个事务
- 入队 将多个命令放入到队列 接收到这些命令不会立即执行 而是放到等待队列里面
- 执行 由EXEC命令触发
不支持原子性:Redis同一个事务里面如果有一条命令执行失败 后面的命令仍然会被执行没有回滚
Redis的主从复制
主从复制:主机数据更新之后根据配置和策略自动同步到备机上面master/slaver机制,Master以写为主 Slave以读为主
主从复制能够实现读写分离和容灾恢复
遵守的规则是配从不配主
修改配置文件的步骤:
- 拷贝多个redis.conf文件
- 开启daemonsize yes
- pid文件名字
- 指定端口
- Log文件名字
- Dump.rdb 名字
配置常用的方式
- 1主2仆
- 薪火相传