一文学懂Redis

目录结构如下:

简介

Redis是一个高性能的key-value数据库。Redis对数据的操作都是原子性的。

优缺点

优点:

  1. 基于内存操作,内存读写速度快。
  2. Redis是单线程的,避免线程切换开销及多线程的竞争问题。单线程是指在处理网络请求(一个或多个redis客户端连接)的时候只有一个线程来处理,redis运行时不止有一个线程,数据持久化或者向slave同步aof时会另起线程。
  3. 支持多种数据类型,包括String、Hash、List、Set、ZSet等
  4. 支持持久化。Redis支持RDB和AOF两种持久化机制,持久化功能有效地避免数据丢失问题。
  5. redis 采用IO多路复用技术。多路指的是多个socket连接,复用指的是复用一个线程。redis使用单线程来轮询描述符,将数据库的开、关、读、写都转换成了事件。多路复用主要有三种技术:select,poll,epoll。epoll是最新的也是目前最好的多路复用技术。

缺点:对join或其他结构化查询的支持就比较差。

io多路复用

将用户socket对应的文件描述符(file description)注册进epoll,然后epoll帮你监听哪些socket上有消息到达。当某个socket可读或者可写的时候,它可以给你一个通知。只有当系统通知哪个描述符可读了,才去执行read操作,可以保证每次read都能读到有效数据。这样,多个描述符的I/O操作都能在一个线程内并发交替地顺序完成,这就叫I/O多路复用,这里的复用指的是复用同一个线程。

应用场景

  1. 缓存热点数据,缓解数据库的压力。
  2. 利用Redis中原子性的自增操作,可以用使用实现计算器的功能,比如统计用户点赞数、用户访问数等,这类操作如果用MySQL,频繁的读写会带来相当大的压力。
  3. 简单消息队列,不要求高可靠的情况下,可以使用Redis自身的发布/订阅模式或者List来实现一个队列,实现异步操作。
  4. 好友关系,利用集合的一些命令,比如求交集、并集、差集等。可以方便搞定一些共同好友、共同爱好之类的功能。
  5. 限速器,比较典型的使用场景是限制某个用户访问某个API的频率,常用的有抢购时,防止用户疯狂点击带来不必要的压力。

给大家分享一个github仓库,上面放了200多本经典的计算机书籍,包括C语言、C++、Java、Python、前端、数据库、操作系统、计算机网络、数据结构和算法、机器学习、编程人生等,可以star一下,下次找书直接在上面搜索,仓库持续更新中~
github地址:https://github.com/Tyson0314/java-books
如果github访问不了,可以访问gitee仓库。
gitee地址:https://gitee.com/tysondai/java-books

Memcached和Redis的区别

  1. Redis只使用单核,而Memcached可以使用多核。
  2. MemCached数据结构单一,仅用来缓存数据,而Redis支持更加丰富的数据类型,也可以在服务器端直接对数据进行丰富的操作,这样可以减少网络IO次数和数据体积。
  3. MemCached不支持数据持久化,断电或重启后数据消失。Redis支持数据持久化和数据恢复,允许单点故障。

数据类型

Redis支持五种数据类型:

  • string(字符串)
  • hash(哈希)
  • list(列表)
  • set(集合)
  • zset(sorted set)

字符串类型

字符串类型的值可以是字符串、数字或者二进制,但值最大不能超过512MB。

常用命令:set, get, incr, incrby, desr, keys, append, strlen

  • 赋值和取值
SET name tyson
GET name
  • 递增数字
INCR num       //若键值不是整数时,则会提示错误。
INCRBY num 2   //增加指定整数
DESR num       //递减数字
INCRBY num 2.7 //增加指定浮点数
  • 其他

keys list* 列出匹配的key

APPEND name " dai" 追加值

STRLEN name 获取字符串长度

MSET name tyson gender male 同时设置多个值

MGET name gender 同时获取多个值

GETBIT name 0 获取0索引处二进制位的值

FLUSHDB 删除当前数据库所有的key

FLUSHALL 删除所有数据库中的key

SETNX和SETEX

SETNX key value:当key不存在时,将key的值设为value。若给定的key已经存在,则SETNX不做任何操作。

SETEX key seconds value:比SET多了seconds参数,相当于SET KEY value + EXPIRE KEY seconds,而且SETEX是原子性操作。

keys和scan

redis的单线程的。keys指令会导致线程阻塞一段时间,直到执行完毕,服务才能恢复。scan采用渐进式遍历的方式来解决keys命令可能带来的阻塞问题,每次scan命令的时间复杂度是O(1),但是要真正实现keys的功能,需要执行多次scan。

scan的缺点:在scan的过程中如果有键的变化(增加、删除、修改),遍历过程可能会有以下问题:新增的键可能没有遍历到,遍历出了重复的键等情况,也就是说scan并不能保证完整的遍历出来所有的键。

scan命令用于迭代当前数据库中的数据库键:SCAN cursor [MATCH pattern] [COUNT count]

scan 0 match * count 10 //返回10个元素

SCAN相关命令包括SSCAN 命令、HSCAN 命令和 ZSCAN 命令,分别用于集合、哈希键及有序集合。

expire
SET password 666
EXPIRE password 5
TTL password //查看键的剩余生存时间,-1为永不过期
SETEX password 60 123abc //SETEX可以在设置键的同时设置它的生存时间

EXPIRE时间单位是秒,PEXPIRE时间单位是毫秒。在键未过期前可以重新设置过期时间,过期之后则键被销毁。

在Redis 2.6和之前版本,如果key不存在或者已过期时返回-1

从Redis2.8开始,错误返回值的结果有如下改变:

  • 如果key不存在或者已过期,返回 -2
  • 如果key存在并且没有设置过期时间(永久有效),返回 -1
type

TYPE 命令用于返回 key 所储存的值的类型。

127.0.0.1:6379> type NEWBLOG
list

散列类型

常用命令:hset, hget, hmset, hmget, hgetall, hdel, hkeys, hvals

  • 赋值和取值
HSET car price 500 //HSET key field value
HGET car price

同时设置获取多个字段的值

HMSET car price 500 name BMW
HMGET car price name
HGETALL car

使用 HGETALL 命令时,如果哈希元素个数比较多,会存在阻塞Redis的可能。如果只需要获取部分field,可以使用hmget,如果一定要获取全部field-value,可以使用hscan命令,该命令会渐进式遍历哈希类型。

HSETNX car price 400 //当字段不存在时赋值,HSETNX是原子操作,不存在竞态条件

  • 增加数字
    HINCRBY person score 60
  • 删除字段
    HDEL car price
  • 其他
HKEYS car //获取key
HVALS car //获取value
HLEN car  //长度

列表类型

常用命令:lpush, rpush, lpop, rpop, lrange, lrem

添加和删除元素

LPUSH numbers 1
RPUSH numbers 2 3
LPOP numbers
RPOP numbers

获取列表片段

LRANGE numbers 0 2
LRANGE numbers -2 -1 //支持负索引 -1是最右边第一个元素
LRANGE numbers 0 -1

向列表插入值

首先从左到右寻找值为pivot的值,向列表插入value

LINSERT numbers AFTER 5 8 //往5后面插入8
LINSERT numbers BEFORE 6 9 //往6前面插入9

删除元素

LTRIM numbers 1 2 删除索引1到2以外的所有元素

LPUSH常和LTRIM一起使用来限制列表的元素个数,如保留最近的100条日志

LPUSH logs $newLog
LTRIM logs 0 99

删除列表指定的值

LREM key count value

  1. count < 0, 则从右边开始删除前count个值为value的元素
  2. count > 0, 则从左边开始删除前count个值为value的元素
  3. count = 0, 则删除所有值为value的元素 `LREM numbers 0 2`

其他

LLEN numbers       //获取列表元素个数LINDEX numbers -1  //返回指定索引的元素,index是负数则从右边开始计算LSET numbers 1 7   //把索引为1的元素的值赋值成7

集合类型

常用命令:sadd, srem, smembers, scard, sismember, sdiff

集合中不能有相同的元素。

增加/删除元素

SADD letters a b cSREM letters c d

获取元素

SMEMBERS lettersSCARD letters   //获取集合元素个数

判断元素是否在集合中
SISMEMBER letters a

集合间的运算

SDIFF setA setB  //差集运算SINTER setA setB //交集运算SUNION setA setB //并集运算

三个命令都可以传进多个键 SDIFF setA setB setC

其他

SDIFFSTORE result setA setB 进行集合运算并将结果存储

SRANDMEMBER key count

随机获取集合里的一个元素,count大于0,则从集合随机获取count个不重复的元素,count小于0,则随机获取的count个元素有些可能相同。

SPOP letters

有序集合类型

常用命令:zadd, zrem, zscore, zrange

zadd zsetkey 50 e1 60 e2 30 e3

Zset(sorted set)是string类型的有序集合。zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是Zset每个元素都会关联一个double(超过17位使用科学计算法表示,可能丢失精度)类型的分数,通过分数来为集合中的成员进行排序。zset的成员是唯一的,但分数(score)可以重复。

有序集合和列表相同点:

  1. 都是有序的;
  2. 都可以获得某个范围内的元素。

有序集合和列表不同点:

  1. 列表基于链表实现,获取两端元素速度快,访问中间元素速度慢;
  2. 有序集合基于散列表和跳跃表实现,访问中间元素时间复杂度是OlogN;
  3. 列表不能简单的调整某个元素的位置,有序列表可以(更改元素的分数);
  4. 有序集合更耗内存。

增加/删除元素

时间复杂度OlogN。

ZADD scoreboard 89 Tom 78 Sophia
ZADD scoreboard 85.5 Tyson      //支持双精度浮点数
ZREM scoreboard Tyson
ZREMRANGEBYRANK scoreboard 0 2  //按照排名范围删除元素
ZREMRANGEBYSCORE scoreboard (80 100 //按照分数范围删除元素,"("代表不包含

获取元素分数

时间复杂度O1。

ZSCORE scoreboard Tyson

获取排名在某个范围的元素列表

Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值