Redis-1-NoSQL&Redis概述&常用数据类型

1 NoSQL数据库简介

1.1 两个问题

在了解Redis之前,先来思考两个问题
1,Session存在哪
2,如何减轻DB的压力

对于上述两个问题,先来看第一个:

在早期分布式应用中,我们将Session存储在某一台服务器A上
但当用户再次访问时,经过负载均衡的调控 请求可能打到了服务器B
然而B并没有存储用户的Session信息 因此造成后续的操作失效
为了解决该问题,可以将
1,将Session存储到cookie中
2,将Session广播复制
上述两种方法都存在缺陷,方案1中由于session存储到了客户端因此存在安全问题
方案二中过于繁琐且浪费额外空间

但有了NoSQL我们可以将Session存储在缓存数据库中
每次用户的请求过来 先到NoSQL数据库中查询
由于NoSQL数据库运行在内存中 因此查询速度快 且KV的结构简单易用

请添加图片描述

对于第二个问题:

当业务扩大时,DB就会出现更多的库更多的表将这些数据放在一台MySQL服务器上是不行的
当大量请求打到服务器上时会伴随大量的IO 为了减轻DB的压力
可以通过读写分离 分库分表等操作来 但这些操作都会在一定程度上破坏业务逻辑

当加入NoSQL数据库时 将访问频繁的数据存储其中
每次可以先访问NoSQL数据库 其运行在内存中的特性可以有效减轻IO压力

在这里插入图片描述

1.2 NoSQL数据库概述

NoSQL=Not Only SQL 意为不仅仅是SQL 是非关系型数据库
NOSQL不依赖业务逻辑方式存储 而是以简单的KV模式存储 因此大大增加了数据库扩展能力
其特点如下:
1,不遵循SQL标准
2,不支持ACID
3,远超于SQL的性能

NoSQL的适用&不适用场景

NoSQL适用于
1,对数据高并发的读写
2,海量数据的读写
3,对数据高可扩展性
典型场景-秒杀

NoSQL不适用于
1,需要ACID事务支持
2,基于SQL的结构化查询存储 处理复杂的关系时

2 Redis6概述和安装

2.1 Redis概述

1,Redis是一个开源的KV存储系统

2,Redis支持的value类型丰富包括string list set zset(有序集合) hash

3,这些数据类型都支持push/pop add/remove及取交集并集等操作 且都是原子性操作

4,Redis支持不同方式的排序

5,为了效率数据全部存储在内存中

6,Redis可以周期性把数据写入磁盘以提供持久性

7,提供了主从同步的机制

2.2 Redis安装

mac下直接使用brew安装即可
brew install redis

redis安装在 /usr/local/Cellar/redis
re配置文件redis.conf在 /usr/local/etc/redis.conf

安装后在bin目录下有如下几个文件
在这里插入图片描述

redis-benchmark 	    性能测试工具
redis-check-aof 		修复有问题的aof文件
redis-check-rdb 		修复有问题的rdb文件
redis-cli 				客户端操作入口
redis-sentinel 			Redis集群使用
redis-server 		    Redis服务器启动命令

可以直接使用命令redis-server前台启动默认使用端口号6379
但并不推荐,通过前台启动的方式,该窗口不能做其他操作
且命令行窗口一旦关闭,Redis服务器停止
在这里插入图片描述
推荐后台启动的方式,修改配置文件或使用brew启动均可
采用ps axu | grep redis查看redis是否启动

redis-server 					启动redis服务
redis-cli  						打开客户端连接本地redis服务
sudo pkill redis-server 		强制关闭redis服务
redis-cli  shutdown				关闭redis客户端

2.3 Redis相关知识

1,redis有16个数据库 默认使用0号库 从0-16
可以使用select dbid来切换数据库 如select 6

2,使用dbsize查看当前库key的数量

3,使用flushdb 清空当前库

4,使用flushall 清空全部库

Redis是单线程+多路IO复用技术,即单线程轮询处理任务处理完callback

3 常用5大数据类型

3.1 Redis中key的操作

1,keys * 
查看当前库中所有key

2,exists key 
判断某个key是否存在

3,type key 
查看某个key的类型

4,del key 
删除指定的key及其对应数据

5,unlink key 
根据value选择非阻塞删除 异步删除

6,expire key 10
给设定的key设置过期时间10秒钟

7,ttl key 
查看key还有多少秒过期 -1表示永久 -2表示已过期

3.2 String

String是Redis中最基本的类型 一个Redis中字符串value最多可以是512M
String类型是二进制安全的 Redis的String可以包括任何数据 如jpg图片或序列化对象

3.2.1 常用命令

1,set key value
向当前库存储K-V记录 存储相同K时会覆盖

2,get key
根据K从当前库取对应V

3,append key value
向K对应的V追加数据

4,strlen key
查看K对应V的长度

5,setnx key value
当K不存在时 才能存储成功

6,incr key
当K对应的是数字时 V自增

7,decr key
当K对应的是数字时 V自减

8,incrby key step
将K对应的数字增加step

9,decrby key step
将K对应的数字减少step

10,mset key1 value1 key2 value2...
设置多组KV

11,mget key1 key2...
取得多组V

12,msetnx key1 value1 key2 value2...
设置多组不存在的KV 有一个失败全失败

13,getrange key 起始位置 结束位置
类似substring 取得K对应V的范围

14,setrange key 起始位置 value
用value覆盖K对应的V 从起始位置开始

15,getset key value
设置K对应V的新值时获取旧值

16,setex key 过期时间 value
设置KV的同时设置过期时间

3.2.2 数据结构

Redis中String的数据结构为简单动态字符串,是可以修改的字符串
内部结上类似于ArrayList,采用预分配冗余空间的方式减少内存频繁分配
请添加图片描述
为字符串分配的capacity一般都大于字符串的len
当字符串长度小于1M时,扩容是翻倍扩容,大于1M时每次扩容增大1M,最大512M

3.3 List

Redis列表是简单的字符串列表,按照插入顺序排序
可以将一个元素加到列表的头或尾
请添加图片描述
底层就是一个双向链表

3.3.1 常用命令

1,lpush/rpush k1 v1 v2 v3
从左边/右边插入K及一个或多个V

2,lpop/rpop key
从key对应的列表左边/右边弹出一个值 值在键在 值空键亡 

3,rpoplpush k1 k2 
从k1列表右边弹出一个值 插到k2列表左边

4,lrange key start end
按照索引下标从key对应的列表从左到右取出元素
0 -1代表所有元素 0作为下标表示左1 -1作为下标表示右1

5,lindex key index
按照索引下标获取元素(从左到右)

6,llen key
获得列表长度

3.3.2 数据结构

Redis中的列表本质是快速链表qucikList
首先当列表元素较少的情况下会使用一块连续的内存,这个结构是ziplist压缩列表
它将所有的元素紧挨着一起存储,分配一块连续内存
请添加图片描述
当数据量较大时会变为quicklist,即多个ziplist通过pre和nxt相连接 进而节省空间
既满足快速插入和删除,又不会出现太多空间冗余(pre和nxt占用的空间)

3.3 Set

Redis的set对外提供的功能与List类似,其特殊处在于set可以自动排重
且set提供了判断某个成员是否在一个set集合内的接口

3.3.1 常用命令

1,sadd k1 v1 v2
将一个或多个元素添加到K中 重复的V会去重

2,smembers key
取出该集合所有值

3,scard key
返回集合的元素个数

4,spop key
从集合中随机弹出一个元素

5,srem key v1 v2
删除集合中的一个或多个元素

3.3.2 数据结构

Redis的set是string类型的无序集合 底层是一个value为null的hash表

3.4 Hash

Redis中的Hash作为value,一个key对应一个hash,一个hash中有多对filed-value

3.4.1 常用命令

1,hset key field value
给key对应的hash的field赋值value

2,hget key field
从key对应的hash中取field的值

3,hkeys key
列出key对应的hash所有field

4,hvals key
列出key对应的hash的所有value

3.4.2 数据类型

Redis中的hash有两种数据类型
当field-value长度较短时且个数较少时使用ziplist
否则使用hashtable

3.5 zset

Redis的有序集合zset与普通集合set非常相似,是无重复元素的有序集合
不同之处是有序集合的每个成员都关联了一个评分(score),这个评分被用来按照从最低分到最高分的方式排序集合中的成员,集合的成员是唯一的,但是评分可以重复

3.5.1 常用命令

1,zadd key score1 value1 score2 value2
将一个或多个元素及其score值加入有序集合key当中

2,zrange key start stop [WITHSCORES]
返回有序集合key中 下标在start到stop间的元素
带[WITHSCORES]时 可以将分数和值一起返回到结果集

3,zrem key value
删除key集合下的value值

4,zrank key value
返回该值在集合中的排名 从0开始

3.5.2 数据结构

zset是Redis中提供一个特别的数据结构,一方面像Map<String, Double>可以给每个元素的value赋予一个权重,另一方面又类似于TreeSet 内部元素可以按照score排序

zset底层使用了两个数据结构hash和跳表

1,hash即Map<String,Double> 关联元素和对应的score
且保证元素的唯一性

2,跳表其目的在于给value排序
根据score的范围获取元素列表

3.5.3 跳表

有序集合在生活中比较常见,如学生成绩排名,游戏rank排名等
对于有序集合底层的实现,可以使用数组,链表,平衡树等
但数组不便插入删除,链表查询效率低,平衡树或红黑树结构复杂

Redis对于有序集合的存储采用跳表来实现
跳表的效率堪比红黑树,实现却远比红黑树简单

以链表和跳表分别查找元素51为例
链表:
请添加图片描述

从头开始查找 比较判断6次

跳表:请添加图片描述

1,从第二层开始,找到1 1<51 找第二层下一个节点 21 21<51 找下一个节点 第二层没有节点 来到第一层
2,找到41 41<51 找第一层下一个节点61 61>51 来到第0层找上一个节点
3,找到51 查询结束

跳表查询效率较高且结构更简单


版权声明:本文为weixin_43541094原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。