redis笔记

一、redis五大类型

1、String:一个key对应一个value

2、List:底层是链表,可以添加一个元素到列表的左右两边,没有值时key会消失

3、Hash(类似Map<String,Map<String,Object>>):K-V模式不变,但V又是一个K-V,适合存储对象

4、Set

5、Sorted Set(有序Set):每个元素都会关联一个double类型的分数,redis通过这个分数来为集合中的成员进行从小到大的排序。这种set的数据是唯一的,但分数是重复的

二、key命令

1、select 1        进入1号库

2、del key        删除key

3、get key        获取某个值

4、move key 2        把key移到2号库

5、keys *            查看所有的key

6、exists key        是否存在key,存在返回1,不存在返回0

7、expire key time        为key设置过期时间为time秒,过期后就被移除了,keys *不会有,get key 为null

8、ttl key            查看key的过期时间,-1为永不过期,-2为过期了

9、type key        查看key的类型

三、string命令

1、set key value        存储string类型的值,相同的key会覆盖

2、append key value    同java中的append

3、strlen key        同java中的String.length()

4、incr key        key+1(如果不存在,会先初始化为0,再加1)

5、decr key        key-1(如果不存在,会先初始化为0,再减1)

6、incrby key number    key+number

7、decrby key number    key-number

8、getrange key index1 index2    类似substring(index2为-1代表全部)

9、setrange key index value    把value覆盖给key从index位置开始,长度为value.length()的值        

10、setex key time value    同expire

11、setnx key value        如果不存在才添加key value

12、mset k1 v1 k2 v2 k3 v3        mget k1 k2 k3    批量添加、查询

13、msetnx k1 v1 k2 v2 k3 v3       mset和setnx的集合体,有一个已经存在,那么整个就不执行

四、List命令

1、lpush/rpush list a b c    从左/右往list中插入数据,容器是个2边开口的队列,取的时候从左往右取

2、lrange list index1 index2    从list中取出index1到index2的值(与getrange类似,index2为-1代表所有)

3、lpop/rpop list        从左/右取第一个出栈,出栈后list中就没这个元素了

4、lindex    list index        从左开始获得list索引index处的值

5、llen list        获得list的长度

6、lrem list number value    从list中删除number个值为value的元素

7、ltrim list index1 index2     把list中index1到index2的值截取出来再赋值给这个list

8、rpoplpush list1 list2    先rpop list1 再 lpush list2 

9、lset list index value    把list索引index处的值设为value

10、linsert list before/after value1 value2    在value1的左/右插入值

五、Set命令

1、sadd set 1 1 2 2 3 4    添加值(重复的会自动去掉)

2、smembers set         取出所有值

3、sismember set value    set中是否有value

4、scard set        有几个元素

5、srem set value        删除set中的值

6、srandmember set number        从set中随机取number个数

7、spop set         随机从set中取值出栈

8、smove set1 set2    value    把set1中的value移到set2中    

9、sdiff set1 set2        在第一个set里而不在第二个set里

10、sinter set1 set2        set1和set2的交集

11、sunion set1 set2    set1和set2的并集

六、hash命令(大写的KEY是大K,小写的key是value里的key)

1、hset KEY key value            赋值

2、hget KEY key

3、hmset KEY key1 value1 key2 value2        批量赋值

4、hmget KEY key1 key2 key3        取出所有对应的value

5、hgetall KEY                取出所有key和value

6、hdel KEY key                删除KEY中的key

7、hexists KEY key

8、hkeys/hvals                得到所有的keys/values

9、hincrby KEY key number            同incrby

10、hincrbyfloat KEY key float        同上

11、hsetnx KEY key value            同setnx

七、Redis持久化

1、RDB:

        每隔一段时间把数据写入到硬盘中。Redis会单独创建(fork)一个子进程来进行持久化,会将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件(dump.rdb),redis也会将硬盘中的数据写入到内存中(可以通过配置文件中的 save 100 10 配置,即100秒内触发了10次修改,就会触发bgsave操作保存dump.rdb)。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。RDB的缺点是最后一次持久化后的数据可能丢失,并且由于fork会复制一份内存中的数据,所有内存会扩大一倍,会有性能问题

        redis的save、bgsave、flushall、shutdown命令会触发rbd启动,存储到dump.rdb文件中。而flushall会删除所有数据,所以没有意义。

     rdb触发条件:

    (1)手动执行save命令,会造成阻塞

    (2)手动执行bgsave命令,不会造成阻塞

    (2)在配置文件中配置的save [seconds] [changes] 满足条件即触发,执行bgsave命令

2、AOF:以日志的形式来记录每个写操作(读操作不记录)

    (1)同步方式(配置文件中配置):

  • always:修改了就同步,性能较差
  • everysec:每秒同步,异步操作,如果宕机会丢失一秒的数据

    (2)重写:默认配置当AOF文件大小是上次重写后大小的一倍且文件大于64M时触发

    (3)劣势:相同情况下aof文件要远大于rdb文件,恢复速度、运行效率慢于rdb

    (4)aof和rdb共存时,优先载入aof文件恢复数据

 

常见面试题

一、缓存雪崩

同一时间redis大面积失效,可能是redis挂了或者数据失效时间同时到达

解决方案:

  • redis culster解决单个redis挂掉的问题
  • 往redis存数据时,每个key的失效时间弄成随机,保证不会同一时间大面积失效

二、缓存穿透

缓存中和数据库中都没有的数据,但用户一直在发送请求,比如id是-1的用户

解决方案:

  • 参数校验
  • 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击

三、缓存击穿

缓存雪崩是大面积的key失效,缓存击穿是一个热点key失效,导致大量请求去访问数据库

解决方案:

  • 布隆过滤器
  • 设置热点数据永远不过期
  • 加互斥锁,缓存中有数据,就直接取缓存中的。如果没有,获取锁,获取成功,则去数据库中查询,然后写入缓存。获取失败,则等待100毫秒,再从头开始从缓存中获取。这样可以保证每次只有一个线程访问数据库,但缺点是高并发时影响效率。比如线程A要获取key1,线程B要获取key2,那这2个线程会相互阻塞,影响效率

四、数据不一致

缓存不一致产生的原因一般是主动更新失败,例如更新 DB 后,更新 Redis 因为网络原因请求超时;或者是异步更新失败导致。

解决方案:

  • 如果服务对耗时不是特别敏感可以增加重试;如果服务对耗时敏感可以通过异步补偿任务来处理失败的更新,或者短期的数据不一致不会影响业务,那么只要下次更新时可以成功,能保证最终一致性就可以。
     

五、为什么这么快

1、绝大部分请求是纯粹的内存操作

2、采用单线程,避免了不必要的上下文切换和竞争条件(单线程指的是网络请求模块使用了一个线程(所以不需考虑并发安全性),即一个线程处理所有网络请求,其他模块仍用了多个线程)

3、非阻塞IO - IO多路复用????

redis实现原理???

哨兵

主从

synchronized 锁对象,锁类,锁代码块的实现原理

synchronized锁升级过程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值