概述Redis是一种NoSQL(Not Only SQL)数据库,即非关系型数据库。正如Java线程、Hadoop、Nginx、MQ、ElasticSearch一样,它的出现也是为了解决程序的关键问题,它可以用来存储关系型数据库难以存储的数据。其可以解决分布式情况下的session登录问题、也可以解决数据库查询时的速度和压力问题等。
1、Redis是一个开源的key-value存储系统。 2、Redis支持的value类型相对较多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set有序集合)和hash(哈希类型) 3、Redis支持value的push/pop、add/remove、取交集、并集、差集等丰富操作,且这些操作都是原子性。 4、Redis支持各种不同方式的排序。 5、Redis的数据都是存储在缓存中,同时也可周期性的把更新的数据写入磁盘。并在此基础上实现了master-slave(主从)同步。
功能举例:
1、通过List类型实现按自然时间排序的数据 —– 获取最新的N个数据。 2、利用zset(有序集合) —– 排行榜,Top N。 3、使用Expire过期 —– 时效性数据。如验证码,登录信息。 4、利用原子性,自增方法INCR、DECR —– 计数器,秒杀服务。 5、利用Set集合 —– 去除大量数据中的重复数据。 6、利用list集合 —– 构建队列。 7、pub/sub模式 —– 发布订阅消息系统。NoSQL扩展
1、NoSQL数据库不依赖业务之间的关系而进行分表存储,而是通过KV键值对的方式进行存储,因此极大地增加了其扩展能力。 2、NoSQL有自己一套规范,不遵循SQL标准,同时不支持ACID(但支持事务),且性能远超关系型数据库。 3、NoSQL适用于高并发常见和海量数据读写的情况。 4、NoSQL不适用于需要事务支持或需要复杂结构关系支持的情况。 5、常用的NoSQL数据库有Memcache(较为古早,不支持持久化,KV存储,类型单一,执行为多线程+锁)、Redis(支持持久化,存储数据类型丰富,执行为单线程+多路IO复用)、mongoDB(文档型数据库,数据可存硬盘,KV存储,查询功能丰富,支持二进制数据及大型对象) 6、NoSQL的使用打破了传统关系型数据库以业务逻辑为依据的存储模式,而针对不同数据结构类型改为以性能为最优先的存储方式。Redis安装
安装版本(视频版本): redis-6.2.1.tar.gz
安装要求: Linux环境下的Redis版本(一般不考虑Windows环境下的版本)。
安装步骤:
1、先下载redis-6.2.1.tar.gz
2、通过xftp传送至Linux的/opt目录下,再通过xshell连接上Linux,进入/opt目录。进行解压前,需要在Linux环境中安装好C语言的编译环境(因为Redis是C语言编写的)。
2.1、安装命令(默认安装在/usr/local/bin目录下):
yum install centos-release-scl scl-utils-build
yum install -y devtoolset-8-toolchain
scl enable devtoolset-8 bash
2.2、或者只安装gcc环境(选一个即可):
yum install gcc
3、解压压缩包。解压命令:
tar -zxvf redis-6.2.1.tar.gz
4、解压完成后进入文件解压目录:
cd/redis-6.2.1
4.1、执行编译命令:
make
4.2、若在make阶段出现问题,首先检查是否安装好C语言编译环境,使用命令: gcc --version 查看是否有版本,若无,使用命令(下载C语言编译环境): yum install gcc。若有,则执行命令: make distclean,然后再执行编译命令make即可。
4.3、执行安装命令(默认安装目录为/usr/local/bin):
make install
4.4、安装目录下共有六个安装文件,其作用分别是:
redis-benchmark: 性能测试工具,可以测试自己的服务器性能如何。
redis-check-aof: 修复有问题的AOF文件。
redis-check-dump: 修复有问题的dump.rdb文件。
redis-sentinel: Redis集群使用。
redis-server: Redis服务器启动命令。
redis-cli: 客户端,操作入口。
5、启动命令:
前台启动(不推荐,不能进行其它操作,窗口关闭即停止,ctrl + c停止服务): redis-server
后台启动(推荐,窗口关闭仍运行,redis-cli shutdown停止服务):
5.1、首先进入/opt/redis-6.2.1.tar.gz目录中,将redis.conf文件复制一份(保留源文件,目的地址哪都行): cp redis.conf /etc/redis.conf。
5.2、修改etc下的配置文件vi /ect/redis.conf,将128行处的daemonize no修改为yes(允许后台启动)
5.3、进入redis默认安装目录: cd /usr/local/bin,执行后台启动命令(后面跟的是复制修改后的redis.conf文件目录):redis-server /etc/redis.conf
5.4、启动成功后,查看redis状态: ps -ef | grep redis
5.5、通过客户端连接上redis命令: redis-cli
知识介绍
1、Redis默认16个库,类似数组下标从0开始,初始默认使用0号库。 2、使用selectRedis数据类型进行数据库切换。如select 8。 3、dbsize命令查看但概念数据库的key数量,flushdb清空当前库,flushall清空所有库。 4、Redis使用的是单线程 + 多路IO复用。多路IO复用的意思是线程提出操作申请,然后去做自己的事情,等到被通知运行操作时,再回来进行操作。
Redis中的共有五大数据类型: 字符串(String)、列表(List)、集合(Set)、哈希(hash)、有序集合(Zset)。Redis键(key)
关于键值的常用命令:
1、keys *
查看当前库的所有key。如(查询一号库所有键): keys *1
2、exists
判断某个key是否存在,存在返回1,不存在返回0。如(判断key a1是否存在): exists a1
3、type
查看key的类型。如(查看键值a的类型): type a
4、del
删除指定的key数据。如(删除键值为a的键值对): del a
5、unlink
根据value选择非阻塞删除。即执行命令后仅将key从keyspace元数据中删除,而真正的删除会在后续异步操作中删除。
6、expire time
给key设置过期时间time(秒)。如(键值a的存活时间为10s): expire a 10
7、ttl
查看key还有多少秒过期,-1表示永不过期,-2表示已过期。如(查询a过期时间): ttl a
关于库的命令:
1、select 库
切换当前使用的数据库。如(切换为使用2号库): select 2
2、dbsize
查看当前数据库的key的数量
3、flushdb
清空当前库
4、flushall
清空所有库
字符串(String)
介绍: 1、String是Redis最基本的类型,一个key对应一个value。 2、String类型是二进制安全的,即只要一个数据类型可以使用字符串表示,就都可以存储到Redis中。 3、一个Redis的字符串value最多可以存储512M数据。 常用命令: 1、set底层数据结构向当前库中添加key对应的value,若key已存在,则直接覆盖。如: set a1 1 2、get 获取当前库中key对应的value。如: get a1 3、append 在key对应的value后追加指定的value,并返回总长度。如: append a1 2 4、strlen 得到key对应的value的长度。 5、setnx 当key不存在时,向当前库中添加key对应的value,若key存在,则设置不成功。 6、incr 当key对应的value为数字时,value加一,如果value为空,则新增值为1。返回增1后的值。 7、decr 当key对应的value为数字时,value减一,如果value为空,则新增值为-1。返回减1后的值。 8、incrby / decrby <步长> 当key对应的value为数字时,增/减对应的值(步长)并返回。改操作均是原子操作,即不会被线程调度机制打断的操作,基于Redis是单线程,这种操作也不会被其它线程打断。 其它命令: 1、mset ... 同时设置一个或多个key-value对。 2、mget ... 同时获取一个或多个value。 3、msetnx ... 当其中所有key都不存在时才设置成功,若其中有一个key已存在,则全部设置失败。 4、getrange <起始位置> <结束位置> 获取指定key对应的value值的下标从<起始位置>到<结束位置>的值。 5、setrange <起始位置> 在key对应的value的下标为<起始位置>处插入 。 6、setex <过期时间> 设置key-value的同时设置<过期时间>(秒)。 7、getset 以新换旧,获取到key对应的旧value的同时设置value为新value。
String的数据结构为简单动态字符串(Simple Dynamic String,缩写为SDS),是可以修改的字符串,其内部结构实现上类似于Java的ArrayList,采用了预分配冗余空间的机制减少内存的频繁分配。即实际使用的内存len小于实际分配的内存capacity,当字符串长度小于1M时,扩容是加倍capacity,当字符串超过1M时,扩容只会每次多扩1M空间,注意String类型最大长度为512M。列表(List)
介绍: 1、单键多值。即一个key对应一个字符串列表,列表有序,并允许添加元素到列表头或列表尾。 2、列表底层由双向链表构成,因此操作两端数据时效率较高,查询或操作中间数据时效率较低。 常用方法: 1、lpush / rpush底层数据结构从左/右边向key对应的列表插入 , , 。如(向a列表中从左依次插入1,2,3): lpush a 1 2 3。最终list为3,2,1。 2、lpop / rpop 从左边/右边弹出key对应的列表的一个值,若值弹完,键亡。 3、rpoplpush 从列表 右边弹出一个值,插入 的左边。 4、lrange 按照 到 下标获取key中对应值。如(获取k1中所有值):lrange k1 0 -1。 5、lindex 按照索引下标 获取 列表中的值。 6、llen 获取key对应的列表的长度。 7、linsert before/after 找到key对应列表从左其第一个 ,在其左边插入 。如(在k1对应列表的左起第一个v1左边插入v0): linsert k1 before v1 v0 8、lrem 从左边其删除key对应列表中的n个 。 9、lset 将key对应列表中下标为 的值替换为 。
1、List底层的数据结构为快速链表qucikList,快速链表其实由压缩列表(zipList)构成,压缩列表即一块连续的内存空间,当列表元素较少时就采用压缩列表存储,其中的元素挨个存储,因此也具有双向链表特征。 2、当列表元素较多时,就再开一片压缩列表空间用来存储列表元素,并与之前的压缩列表互相指向。 3、Redis采用这种存储方法的原因为: 若每个列表元素都附加两个指针,那么内存开销会很大,因此使用zipList进行互相指向减少内存消耗,zipList中的元素由于连续,也拥有双向链表的特性。集合(Set)
介绍: 1、Set提供的功能与List类似,也是[key-列表]结构,不同点在于Set可以自动去重且无序的。 2、Set是String类型的无序集合,其底层实际上是一个value为null的hash表,因此添加,删除,修改的时间复杂度都为O(1)。 常用方法: 1、sadd底层数据结构... 将一个或多个member元素加入到key对应的Set中,已经存在的member元素会被忽略。 2、smembers 取出 对应的Set中的所有值。 3、sismember 判断 对应的Set中是否存在值 ,存在返回1,不存在返回0。 4、scard 返回key对应的Set中元素个数。 5、srem ... 删除key对应的Set中的元素 , ..。 6、spop 随机从key对应的Set中弹出一个值。 7、srandmember 随机从key对应的Set中获取 个value,不会进行删除操作。 8、smove 把 从 集合中移到 集合中。 9、sinter 返回key1和key2分别对应的Set的交集元素。 10、sunion 返回key1和key2分别对应的Set的并集元素。 11、sdiff 返回两个集合的差集元素(key1中包含的,不包含key2中的)。
Set底层数据结构其实是hash结构,所有的value都指向同一个内部值。哈希(Hash)
介绍: 1、哈希也是一个键值对集合,每个键值对都是一个String类型key对应一个或多个field和value的键值对,hash适合存储对象,其类似于Java中的Map底层数据结构。 即: key value field value id 1 user -> name 张三 age 20 常用命令: 1、hset 给 对应哈希的 赋值为 。 2、hget 从 对应哈希中取 对应的value。 3、hmset ... 批量设置key1对应hash的值。 4、hexists 查看哈希表key1中是否存在给定域 。 5、hkeys 列出该hash集合中所有的field。 6、hvals 列出该hash集合中所有的value。 7、hincrby 为哈希表key中的域field对应的value加上增量 8、hsetnx 当且仅当域field不存在时,将哈希表key中的域field的值设置为value。
Hash类型对应的数据结构为两种: zipList(压缩列表),hashtable(哈希表)。当field-value长度较短且个数较少时,使用zipList,否则使用hashtable。有序集合(ZSet)
介绍: 1、ZSet和Set非常相似,都是一个没有重复元素的字符串集合。不同之处为ZSet中每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排序ZSet中的成员,集合中的成员是唯一的,单评分可以重复。 2、因为ZSet中的元素是有序的,因此可以很快通过评分(score)或者次序(position)来获取一个范围的元素。 3、访问ZSet的中间元素也是非常快的,因此能够使用ZSet作为一个没有重复成员的智能列表。 常用方法: 1、zadd... 将一个或多个member元素及其score值加入到有序集合key中。 2、zrange [WITHSCORES] 返回有序集key中,下标在 与 之间的元元素,若携带[WITHSCORES],则可以让分数一起和值返回到结果集。如(查询topn有序集合中带分数的所有元素): zrange topn 0 -1 withscores 3、zrangebyscore [withscores] [limit offset count] 返回有序集合key中的score处于 到 之间的元素,包括min和max。且返回元素按score从小到大排序。 4、zrevrangebyscore [withscores] [limit offset count] 返回有序集合key中的score处于 到 之间的元素,包括min和max。且返回元素按score从大到小排序。 5、zincrby 为有序集合 的元素 的score增加增量 。如(为topn有序集合中的Java的scores增加100): zincrby topn 100 Java 6、zrem 删除该集合下指定的 值。 7、zcount 统计该集合下指定分数区间内的元素个数。包含左右。 8、zrank 返回该值在集合中的排序,下标从0开始



