本文分享本菜鸟的Redis学习笔记,稍微有点乱。
Redis是一个开源的key-value存储系统,数据都在内存中,支持持久化。支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。
本菜鸟QQ:599903582
一起学习,共同进步。
比心心 ~
提示:以下是本篇文章正文内容,下面案例可供参考
NoSQL, 泛指非关系型数据库。NoSQL 不依赖业务逻辑方式存储,是以简单的 key-value模式存储。因此大大的增加了数据库的扩展能力。不遵守SQL标准。不支持ACID。远超于SQL的性能。
对数据高并发的读写。
海量数据的读写。
对数据高扩展性的。
需要事务支持。
基于SQL的结构化查询存储,处理复杂的关系,需要即席查询。
注意:用不着SQL的和用了SQL也不行的情况下,考虑NoSQL。
缓存数据库:
Memcached: 数据都在内存中,一般不支持持久化,简单的k-v类型,一般作为缓存数据库辅助持久化数据库;
Redis:数据都在内存中,支持持久化,只要做备份恢复,支持多种数据类型:list、set、hash、zset等,一般作为缓存数据库辅助持久化的数据库;
文档数据库:
列式数据库:
Redis是一个开源的key-value存储系统。
支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,Redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是Redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
1.开启服务:
bin/redis-server /root/myredis/redis.conf
2.客户端访问:
bin/redis-cli
bin/redis-cli -p 6379
3.测试
redis-cli连接后,输入 ping 输出 pong
4.关闭
bin/redis-cli shutdonw 或 进入 redis-cli 然后 shutdown
5.多实例关闭
bin/redis-cli -p 6379 shutdown
端口6379
默认16个数据库,类似数组下标从0开始,初始默认使用0号库,使用命令 select 来切换数据库。如: select 8
统一密码管理,所有库都是同样密码,要么都OK要么一个也连接不上。
Redis是单线程+多路IO复用技术
多路复用:
多路复用是指使用一个线程来检查多个文件描述符(Socket)的就绪状态,比如调用select和poll函数,传入多个文件描述符,如果有一个文件描述符就绪,则返回,否则阻塞直到超时。得到就绪状态后进行真正的操作可以在同一个线程里执行,也可以启动线程执行(比如使用线程池)。
key+ string
set
list
hash
zset
key
keys * : 查询当前库的所有键
exists :判断某个键是否存在
type :判断键对应的数据类型
del :删除某个键
expire :为键值设计过期时间
ttl : 查看还有躲闪秒过期, -1代表永不过期 , -2 代表已过期
dbsize :查看当前数据库的key数量
flushdb : 清空数据库
flushall:通杀所有数据库
String:
get : 查询对应键值
set :添加键值对
append : 将给定的value追加到原值的末尾
strlen :获得值的长度
setnx :只有在key不存在时设置key的值
incr :将key中存储的数字值增1,如果为空,新增值为1
decr :将key中存储的数字值减1,如果为空,新增值为-1
incrby / decrby <步长> :自定义步长
mset : 同时设置一个或多个
mget :同时获得多个
msetnx :key都不存在时
getrange <起始位置><结束位置> :获得值的范围
setrange <起始位置> :从<开始位置>开始覆写
setex <过期时间>:设置键的同时,设置过期时间
getset : 以旧换新,设置新值的同时获取旧值
List:
lpush/rpush :从左边、右边插入一个或多个值
lpop/rpop : 从左边或右边吐出一个值,值亡键亡
rpoplpush:从key1右边吐出一个值,插到key2左边
lrange:按照索引下标获得元素(从左到右)
lindex:根据索引下标获取元素(从左到右)
llen :获取列表长度
linsert before :在value的前面插入newvalue
lrem :从左边删除n个value (从左到右)
Set:
sadd :将一个或多个member元素加入到集合key中,已经存在的member元素被忽略
smember :取出该集合的所有值
sismember :判断集合是否存在value,有1,无0
scard :返回该集合的元素个数
srem :删除元素的某个元素
spop :随机从集合中吐出一个或多个值
srandmember :随机从集合中取出n个值,不删除
sinter :集合交集
sunion :集合并集
sdiff :集合差集
Hash:
hset :给集合中的赋值
hget :从集合中取出field
hmset :批量设置hash的值
hexists :查看哈希表key中,field是否存在
hkeys :列出该集合中所有的field
hvals :列出集合中的所有value
hincrby :给field值加上increament
hsetnx :为field设值,当field不存在的时候
Zset:
zadd :将一个或多个member元素及其score值加入到有序集key中
zrange [withscores]:返回有序集key中,下标在之间的元素,可以让分数一起返回
zrangebyscore min max[withscores]:返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score 值递增(从小到大)次序排列。
zrevrangebyscore key max min [withscores]:从大到小
zincrby :为元素的score加上增量
zrem :删除该集合下,指定值的元素
zcount :统计该集合,分数区间内的元素个数
zrank : 返回该值在集合中的排名,从0开始
Redis事务是一个单独的隔离操作:
事务中的所有命令都会序列化、按顺序地执行。
事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
Redis事务的主要作用就是串联多个命令防止别的命令插队。
两种持久化方式:
RDB:在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里。
AOF:以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,Redis启动之初会读取该文件重新构建数据,换言之,Redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
RDB:在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里。
备份是如何执行的?
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能.如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。
RDB的缺点是最后一次持久化后的数据可能丢失。
fork:
在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,Linux中引入了“写时复制技术”,一般情况父进程和子进程会共用同一段物理内存,只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程.
在redis.conf中配置文件名称,默认为dump.rdb
dbfilename dump.rdb
rdb文件的保存路径,也可以修改。默认为Redis启动时命令行所在的目录下
dir ./
stop-writes-on-bgsave-error yes
当Redis无法写入磁盘的话,直接关掉Redis的写操作
rdbcompression yes
进行rdb保存时,将文件压缩
rdbchecksum yes
在存储快照后,还可以让Redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能.
rdb的备份
先通过config get dir 查询rdb文件的目录
将*.rdb的文件拷贝到别的地方
rdb的恢复
关闭Redis
先把备份的文件拷贝到工作目录下
启动Redis, 备份数据会直接加载
rdb的优点
节省磁盘空间
恢复速度快
rdb的缺点
虽然Redis在fork时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能。在备份周期在一定间隔时间做一次备份,所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有修改。
AOF:
以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录)只许追加文件但不可以改写文件,Redis启动之初会读取该文件重新构建数据,换言之,Redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
AOF默认不开启,需要手动在配置文件中配置
appendonly no
可以在redis.conf中设置文件名称,默认为appendonly.aof
appendfilename "appendonly.aof"
AOF文件的保存路径和RDB的路径一致。
AOF和RDB同时开启,redis听谁的?
AOF和RDB同时开启,系统默认取AOF的数据
AOF文件故障备份
AOF的备份机制和性能虽然和RDB不同, 但是备份和恢复的操作同RDB一样,都是拷贝备份文件,需要恢复时再拷贝到Redis工作目录下,启动系统即加载。
AOF文件故障恢复
AOF文件的保存路径,同RDB的路径一致。
如遇到AOF文件损坏,可通过 redis-check-aof --fix appendonly.aof 进行恢复
Rewrite
AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集.可以使用命令bgrewriteaof。
Redis如何实现重写?
AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),遍历新进程的内存中数据,每条记录有一条的Set语句。重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
AOF的优点
备份机制更稳健,丢失数据概率更低。
可读的日志文本,通过操作AOF稳健,可以处理误操作。
AOF的缺点
比起RDB占用更多的磁盘空间
恢复备份速度要慢。
每次读写都同步的话,有一定的性能压力。
存在个别Bug,造成恢复不能.
官方推荐两个都启用。
如果对数据不敏感,可以选单独用RDB。
不建议单独用 AOF,因为可能会出现Bug。
如果只是做纯内存缓存,可以都不用。
搭建教程:
主从复制,就是主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主。
info replication : 打印主从复制的相关信息
slaveof :成为某个实例的从服务器
复制原理:
每次从机联通后,都会给主机发送sync指令,主机立刻进行存盘操作,发送RDB文件,给从机,从机收到RDB文件后,进行全盘加载,之后每次主机的写操作,都会立刻发送给从机,从机执行相同的命令
哨兵模式:
redis目录下新建sentinel.conf文件
在配置文件中填写内容:
sentinel monitor mymaster 127.0.0.1 6379 1
其中mymaster为监控对象起的服务器名称, 1 为 至少有多少个哨兵同意迁移的数量
启动哨兵
redis-sentinel /myredis/sentinel.conf
搭建链接:
Redis 集群实现了对Redis的水平扩容,即启动N个redis节点,将整个数据库分布存储在这N个节点中,每个节点存储总数据的1/N。
Redis 集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。
cluster nodes 查看集群消息
一个集群至少有三个主节点,加上三个从节点,一共需要六个节点。
分配原则尽量保证每个主数据库运行在不同的IP地址,每个从库和主库不在一个IP地址上。
什么是slots:
一个 Redis 集群包含 16384 个插槽(hash slot), 数据库中的每个键都属于这 16384 个插槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。集群中的每个节点负责处理一部分插槽。
举个例子, 如果一个集群可以有主节点, 其中:
节点 A 负责处理 0 号至 5500 号插槽。
节点 B 负责处理 5501 号至 11000 号插槽。
节点 C 负责处理 11001 号至 16383 号插槽。
在redis-cli每次录入、查询键值,redis都会计算出该key应该送往的插槽,如果不是该客户端对应服务器的插槽,redis会报错,并告知应前往的redis实例地址和端口。
redis-cli客户端提供了 –c 参数实现自动重定向。如 redis-cli -c –p 6379 登入后,再录入、查询键值对可以自动重定向。
不在一个slot下的键值,是不能使用mget,mset等多键操作。
可以通过**{}来定义组的概念**,从而使key中{}内相同内容的键值对放到一个slot中去。
查询集群中的值:
CLUSTER KEYSLOT 计算键 key 应该被放置在哪个槽上。
CLUSTER COUNTKEYSINSLOT 返回槽 slot 目前包含的键值对数量。
CLUSTER GETKEYSINSLOT 返回 count 个 slot 槽中的键。
Redis 集群提供了以下好处:
实现扩容
分摊压力
无中心配置相对简单
Redis 集群的不足:
多键操作是不被支持的
多键的Redis事务是不被支持的。lua脚本不被支持。
由于集群方案出现较晚,很多公司已经采用了其他的集群方案,而代理或者客户端分片的方案想要迁移至redis cluster,
需要整体迁移而不是逐步过渡,复杂度较大。
public class JedisClusterTest {
public static void main(String[] args) {
Set set =new HashSet();
set.add(new HostAndPort("192.168.1.100",6379));
JedisCluster jedisCluster=new JedisCluster(set);
jedisCluster.set("k1", "v1");
System.out.println(jedisCluster.get("k1"));
}
}
https://www.redis.net.cn/
本文分享了本菜鸟的Redis学习笔记,稍微有点乱,但是还能看。
本菜鸟QQ:599903582
笨鸟先飞,熟能生巧。
比心心 ~