6379

首先介绍redis默认端口号为6379,为什么嘞,主要粉丝效应!

#redis中文命令手册
https://www.redis.com.cn/commands.html


docker pull redis
下载redis

如使用非root用户,则需要在命令前加上sudo命令,否则会报错

sudo mkdir -p /mydata/redis/conf
sudo touch /mydata/redis/conf/redis.conf
创建redis.conf 配置文件

[root@localhost ~]# docker run -p 6379:6379 --name redis -v /mydata/redis/data:/data -v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf -d redis redis-server /etc/redis/redisnbZX.conf
启动redis

[root@localhost ~]# docker exec -it redis redis-server -v
Redis server v=6.0.10 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=66898bb7acd47e81
此上代码为查看redis版本,可以看出我的版本下载的位6.0.10

[root@localhost ~]# docker exec -it redis redis-cli
docker连接redis容器命令↑

127.0.0.1:6379> ping
PONG
输入ping如显示pong则启动测试成功

127.0.0.1:6379> set name xiaoxue
OK
127.0.0.1:6379> get name
“xiaoxue”
127.0.0.1:6379> keys *

  1. “name”
  2. “a”
    此上为测试redis功能

127.0.0.1:6379> shutdown
关闭redis

**

性能测试

**
redis-benchmark是一个压力测试工具 !
官方自带的性能测试工具 !
redis-benchmark命令参数 !

上图参数来自菜鸟教程

[root@192 bin]# redis-benchmark -h localhost -p 6379 -c 100 -n 100000
linux下测试性能

[root@192 bin]# docker exec -it 705c1a53a8bf redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000
以上为docker镜像下调用压测命令
上图为测试过程

基础知识

redis默认有16个数据库
默认是第0个

127.0.0.1:6379> select 3 #切换数据库
OK
127.0.0.1:6379[3]> DBSIZE # 查看DB大小!
(integer) 0

127.0.0.1:6379[1]> keys *

  1. “name”
    keys * 查看数据库所以的key

127.0.0.1:6379[1]> flushdb
OK
127.0.0.1:6379[1]> keys *
(empty array)
flushdb 清除当前数据库

127.0.0.1:6379[3]> flushall
OK
127.0.0.1:6379[3]> keys *
(empty array)
127.0.0.1:6379[3]> select 0
OK
127.0.0.1:6379> keys *
(empty array)
flushall 清空所有数据库内容

Redis是单线程的!
Redis是很快的,官方表示,Redis是基于内存操作,CPU不是Redis性能瓶颈,Redis的瓶颈是根据机器的内存和网络带宽,既然可以使用单线程实现,就使用单线程了!

Redis 是C语言写的,官方提供的数据为 100000+ 的QPS ,这个完全不比同样使用key-value的Memecache差!
Redis为什么单线程还这么快?
1、误区1:高性能的服务器一定是多线程的?
2、误区2:多线程(CPU上下文会切换! )一定比单线程效率高!
CPU>内存>硬盘的速度要有所了解 !
核心: redis是将所有的数据全部放在内存中的,所以说使用单线程去操作效率就是最高的,多线程(CPU上下文会切换:耗时的操作! ! !),对于内存系统来说,如果没有上下文切换效率就是最高的!多次读写都是在一个CPU上的,在内存情况下,这个就是最佳的方案 !

五大数据类型
Redis-Key
String
List
Set
Hash
Zset
三种特殊数据类型
geospatial
hyperloglog
bitmaps

127.0.0.1:6379> EXISTS name # 判断当前key是否存在,存在返回1,不存在返回0
(integer) 1
127.0.0.1:6379> EXISTS number
(integer) 0
127.0.0.1:6379> move name 1 # 移除当前key
(integer) 1
EXPIRE name 5 #设置key过期时间,单位是秒,过期后会自动删除
(integer) 0
127.0.0.1:6379> ttl name #查看当前key剩余时间
(integer) 2
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> get name
“shsha”
127.0.0.1:6379> type name #查看当前key的类型
string

String(字符串)

127.0.0.1:6379> set xue c
OK
127.0.0.1:6379> get xue
“c”
127.0.0.1:6379> APPEND xue " big" #追加字符串,如果当前key不存在,该命令相当于set key
(integer) 5
127.0.0.1:6379> get xue
“c big”
127.0.0.1:6379> STRLEN xue # 获取字符串长度
(integer) 5

127.0.0.1:6379> set mones 0 #初始浏览量为0
OK
127.0.0.1:6379> get mones
“0”
127.0.0.1:6379> incr views #自增1 浏览量+1
(integer) 1
127.0.0.1:6379> get mones
“0”
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> decr views #自减1浏览量-1
(integer) 1
127.0.0.1:6379> decr views
(integer) 0
127.0.0.1:6379> decr views
(integer) -1
127.0.0.1:6379> get mones
“0”
127.0.0.1:6379> INCRBY mones 10 #可以设置指定增量
(integer) 10
127.0.0.1:6379> DECRBY mones 8 #可以设置指定减量
(integer) 2
127.0.0.1:6379> get mones
“hello mones”
127.0.0.1:6379> GETRANGE mones 0 3 #截取指定字符串[0,3]
“hell”
127.0.0.1:6379> GETRANGE mones 0 -1 #获取全部的字符串,和get key一样
“hello mones”
127.0.0.1:6379> get mones2
“asdfgh”
127.0.0.1:6379> SETRANGE mones2 1 nn #替换指定位置开始的字符串
(integer) 6
127.0.0.1:6379> get mones2
“annfgh”

setex #设置过期时间
setnx #不存在在设置(分布式锁中常用)

127.0.0.1:6379> setex mones3 10 “hi baby” #设置mones3 的值为 hi baby,10秒后过期
OK
127.0.0.1:6379> setnx monesluna “redis” #如果monesluna存在,创建失败
(integer) 1

127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 #批量设置,同时设置多个值
OK
127.0.0.1:6379> keys *

  1. “k3”
  2. “k2”
  3. “k1”
    127.0.0.1:6379> mget k1 k2 k3 #批量获取key值,同时获取多个值
  4. “v1”
  5. “v2”
  6. “v3”
    127.0.0.1:6379> msetnx k1 v1 k4 v4 #msetnx是一个原子性操作,要么一起成功,要么一起失败
    (integer) 0
    127.0.0.1:6379> set user:1 {name:zhangsan,age:3}#设置一个user:1对象 值为json字符来保存一个对象!
    OK
    127.0.0.1:6379> get user:1
    “{name:zhangsan,age:3}”

#以下为key的巧妙设计: user:{id}:{filed} ,如此设计在Redis中完全ok!
127.0.0.1:6379> mset user:1:name lisi user:1:age 10
OK
127.0.0.1:6379> mget user:1:name user:1:age

  1. “lisi”
  2. “10”

##getset #先get然后set
127.0.0.1:6379> getset db redis #如果不存在值,则返回nil
(nil)
127.0.0.1:6379> get db
“redis”
127.0.0.1:6379> getset db mongodb #如果存在值,则返回原来的值,并设置成新值
“redis”
127.0.0.1:6379> get db
“mongodb”

小总结:String类似的使用常见:value除了是我们的字符串还可以是我们的数字!
●计数器
●统计多单位的数量
●粉丝数
●对象缓存存储!

List(列表)

在redis里,可以把list玩成,栈,队列,阻塞队列!
所以list命令 以l开头,redis不区分大小写命令

127.0.0.1:6379> LPUSH list one #将一个值或多个值,插入到列表头部(左)
(integer) 1
127.0.0.1:6379> LPUSH list two
(integer) 2
127.0.0.1:6379> LPUSH list three
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1

  1. “three”
  2. “two”
  3. “one”
    127.0.0.1:6379> LRANGE list 0 1
  4. “three”
  5. “two”
    127.0.0.1:6379> RPUSH list four #将一个或多个值,插入到列表尾部(右)
    (integer) 4
    127.0.0.1:6379> LRANGE list 0 -1
  6. “three”
  7. “two”
  8. “one”
  9. “four”

127.0.0.1:6379> Lpop list #移除list第一个元素
“three”
127.0.0.1:6379> LRANGE list 0 -1

  1. “two”
  2. “one”
  3. “four”
    127.0.0.1:6379> Rpop list #移除list最后一个元素
    “four”
    127.0.0.1:6379> LRANGE list 0 -1
  4. “two”
  5. “one”

127.0.0.1:6379> Lindex list 1 #通过下标获得list中的某一个值
“one”
127.0.0.1:6379> Lindex list 0
“two”
127.0.0.1:6379> llen list #返回列表的长度
(integer) 2
127.0.0.1:6379> lrem list 1 one #移除list集合中指定个数的value,精确匹配
(integer) 1

127.0.0.1:6379> Rpush mylist “mones1”
(integer) 1
127.0.0.1:6379> Rpush mylist “mones2”
(integer) 2
127.0.0.1:6379> Rpush mylist “mones3”
(integer) 3
127.0.0.1:6379> Rpush mylist “mones4”
(integer) 4
127.0.0.1:6379> Ltrim mylist 1 2 #通过下标截取指定位置的长度,这个list已经被改变,只剩下截取的元素
OK
127.0.0.1:6379> LRANGE mylist 0 -1

  1. “mones2”
  2. “mones3”

127.0.0.1:6379> Rpush mylist “ss”
(integer) 1
127.0.0.1:6379> Rpush mylist “dd”
(integer) 2
127.0.0.1:6379> Rpush mylist “cc”
(integer) 3
127.0.0.1:6379> Rpush mylist “ff”
(integer) 4
127.0.0.1:6379> RpopLpush mylist myotherlist #移除列表中的最后一个元素,将他移动到新的列表中
“ff”
127.0.0.1:6379> LRANGE mylist 0 -1 #查看原来的列表

  1. “ss”
  2. “dd”
  3. “cc”
    127.0.0.1:6379> LRANGE myotherlist 0 -1 #查看目标列表中,确实存在该值
  4. “ff”

127.0.0.1:6379> lRANGE mylist 0 -1

  1. “ss”
  2. “dd”
  3. “cc”
    127.0.0.1:6379> lset mylist 0 haha #将列表中指定下标的值,替换为另外一个值,更新操作,如果列表不存在或没有该索引,则会报错(error)
    OK
    127.0.0.1:6379> lRANGE mylist 0 -1
  4. “haha”
  5. “dd”
  6. “cc”

Linsert #将某个具体的value插入到列表中某个元素的前面或后面
127.0.0.1:6379> LRANGE list 0 -1

  1. “aa”
  2. “bb”
  3. “cc”
  4. “dd”
    127.0.0.1:6379> LINSERT list before bb hello #linsert before 插入到某元素前面
    (integer) 5
    127.0.0.1:6379> LRANGE list 0 -1
  5. “aa”
  6. “hello”
  7. “bb”
  8. “cc”
  9. “dd”
    127.0.0.1:6379> LINSERT list after cc mones #linsert before 插入到某元素后面
    (integer) 6
    127.0.0.1:6379> LRANGE list 0 -1
  10. “aa”
  11. “hello”
  12. “bb”
  13. “cc”
  14. “mones”
  15. “dd”

list小结
●他实际上是一个链表,before Node after ,left,right都可以插入值
●如果key不存在,创建新的链表
●如果key存在,新增内容
●如果移除了所以值,空链表,也代表不存在!
●在两边插入或者改动值,效率最高!中间元素,相对啦爱说效率会低一些

消息排队 !消息队列 (Lpush Rpop),栈(Lpush Lpop)

Set(集合)

set无序不重复 set中的值是不能重复的
127.0.0.1:6379> sadd myset “hello” #set集合中添加元素
(integer) 1
127.0.0.1:6379> sadd myset “mones”
(integer) 1
127.0.0.1:6379> sadd myset “luna”
(integer) 1
127.0.0.1:6379> Smembers myset #查看指定set的所有值

  1. “hello”
  2. “luna”
  3. “mones”
    127.0.0.1:6379> Sismember myset “hello” #判断某一个值是不是在set集合中存在返回1
    (integer) 1
    127.0.0.1:6379> Sismember myset sss##判断某一个值是不是在set集合中存在返回1,不存在返回0
    (integer) 0
    127.0.0.1:6379> scard myset #获取set集合中的元素个数!
    (integer) 3
    127.0.0.1:6379> srem myset hello #移除set集合中指定元素
    (integer) 1
    127.0.0.1:6379> scard myset
    (integer) 2
    127.0.0.1:6379> smembers myset
  4. “luna”

127.0.0.1:6379> SRANDMEMBER myset #随机抽选出一个元素
“hahah”
127.0.0.1:6379> SRANDMEMBER myset
“mones”
127.0.0.1:6379> SRANDMEMBER myset 2 #随机抽选出指定个数的元素

  1. “nanan”
  2. “mones”

127.0.0.1:6379> smembers myset

  1. “nanan”
  2. “luna”
  3. “hahah”
  4. “mones”
    127.0.0.1:6379> spop myset #随机删除某一个set集合中的元素
    “hahah”
    127.0.0.1:6379> smembers myset
  5. “nanan”
  6. “luna”
  7. “mones”

127.0.0.1:6379> sadd myset hello
(integer) 1
127.0.0.1:6379> sadd myset world
(integer) 1
127.0.0.1:6379> sadd myset mones
(integer) 1
127.0.0.1:6379> sadd myset luna
(integer) 1
127.0.0.1:6379> smove myset myset2 “mones” #将一个指定的值,移动到另外一个set集合
(integer) 1
127.0.0.1:6379> smembers myset

  1. “hello”
  2. “world”
  3. “luna”
    127.0.0.1:6379> smembers myset2
  4. “mones”
    sdiff 差集 sinter交集 sunion并集

Hash(哈希)

Map集合,key-map 这个值是一个map集合 !

127.0.0.1:6379> hset maphash key1 mones #set一个具体的key -value
(integer) 1
127.0.0.1:6379> hset maphash key2 luna
(integer) 1
127.0.0.1:6379> hget maphash key1 #get一个具体的key
“mones”
127.0.0.1:6379> hget maphash key2
“luna”
127.0.0.1:6379> hmset maphash key1 thanks key2 thanks2 #设置多个key-value
OK
127.0.0.1:6379> hmget maphash key1 key2 #获取多个key-value

  1. “thanks”
  2. “thanks2”
    127.0.0.1:6379> hdel maphash key1 #删除hash指定key字段!对应的value值也就消失了
    (integer) 1
    127.0.0.1:6379> hgetall maphash #获取全部数据
  3. “key2”
  4. “thanks2”
    127.0.0.1:6379> hlen maphash #获取hash表的字段数量
    (integer) 1

127.0.0.1:6379> HEXISTS maphash key2 #判断hash中指定字段是否存在,存在返回1,否则返回0
(integer) 1
127.0.0.1:6379> HEXISTS maphash key1
(integer) 0

127.0.0.1:6379> hkeys maphash #获得所有key

  1. “key2”
    127.0.0.1:6379> hvals maphash #获取所有value
  2. “thanks2”

Zset(有序集合)

在set的基础上,增加了一个值,set k1 v1 zset k1 score1 v1
127.0.0.1:6379> zadd score 500 xiaoxue #zset集合中添加元素
(integer) 1
127.0.0.1:6379> zadd score 300 dige
(integer) 1
127.0.0.1:6379> zadd score 600 pipi
(integer) 1
#ZRANGEBYSCORE key min max
127.0.0.1:6379> ZRANGEBYSCORE score -inf +inf #显示全部的用户 从小到大

  1. “dige”
  2. “xiaoxue”
  3. “pipi”
    127.0.0.1:6379> zrevrange score 0 -1 #显示全部用户 从大到小
  4. “xiaoxue”
  5. “dige”

127.0.0.1:6379> ZRANGEBYSCORE score -inf +inf withscores #显示全部的用户并且附带成绩

  1. “dige”
  2. “300”
  3. “xiaoxue”
  4. “500”
  5. “pipi”
  6. “600”
    127.0.0.1:6379> ZRANGEBYSCORE score -inf 550 withscores #显示score小于550的员工的升序排列
  7. “dige”
  8. “300”
  9. “xiaoxue”
  10. “500”
    ##############
    127.0.0.1:6379> zrange score 0 -1 #遍历有序集合
  11. “dige”
  12. “xiaoxue”
  13. “pipi”
    127.0.0.1:6379> zrem score pipi #移除有序集合中的指定元素
    (integer) 1
    127.0.0.1:6379> zrange score 0 -1
  14. “dige”
  15. “xiaoxue”
    127.0.0.1:6379> zcard score #获取有序集合中的个数
    (integer) 2
    127.0.0.1:6379> zadd myset 1 hello 2 world 3 xiaoxue #批量插入
    (integer) 3
    127.0.0.1:6379> zcount myset 1 3 #获取指定区间的成员数量!
    (integer) 3
    127.0.0.1:6379> zcount myset 1 2
    (integer) 2

其余的一些API,通过我们的学习,剩下的,如果工作中有需要,可以去查看官方文档!官方文档是最正确的!
案例思路:zset 排序 存储班级成绩表,工资表排序
普通消息 1,重要消息 2,带权重进行判断 !
排行榜应用实现,取Top N测试 !

三种特殊数据类型

geospatial 地理位置

朋友的定位,附近的人,打车距离计算?
Redis的Geo 在Redis3.2版本就推出了!这个功能可以推算地理位置的信息,两地之间的举例,方圆几里的人!

可以查询一些测试数据:http://www.jsons.cn/xiehouyu/
只有六个命令

官方文档:https://www.redis.net.cn/order

geoadd:添加地理位置的坐标。
规则:两级无法直接添加,我们一般会下载城市数据,直接通过java程序一次性导入!
有效的经度从-180度到180度。
有效的纬度从-85.05112878度到85.05112878度。
当坐标位置超出上述指定范围时,该命令将会返回一个错误。

127.0.0.1:6379> geoadd china:city 22.547 114.08 shenzhen
(integer) 1
127.0.0.1:6379> geoadd china:city 31.242 121.18 shanghai
(integer) 1
127.0.0.1:6379> geoadd china:city 118.80 32.06 nanjing
(integer) 1
127.0.0.1:6379> geoadd china:city 106.55 29.56 chongqing
(integer) 1
127.0.0.1:6379> geoadd china:city 125.15 42.93 xian
(integer) 1
127.0.0.1:6379> geoadd china:city 114.65 33.60 zhoukou
(integer) 1

geopos:获取地理位置的坐标。
127.0.0.1:6379> GEOPOS china:city xian chongqing zhoukou

    1. “125.1499977707862854”
    2. “42.93000069610238256”
    1. “106.5499994158744812”
    2. “29.56000053864853072”
    1. “114.65000241994857788”
    2. “33.59999880983598786”
      127.0.0.1:6379> GEOPOS china:city nanjing
    1. “118.80000203847885132”
    2. “32.06000108754685129”

geodist:计算两个位置之间的距离。
单位:
● m 表示单位为米
● km 表示单位为千米
● mi 表示单位为英里
● ft 表示单位为英尺

127.0.0.1:6379> GEODIST china:city chongqing zhoukou
“888935.4795”
127.0.0.1:6379> GEODIST china:city nanjing xian
“1331555.6271”
127.0.0.1:6379> GEODIST china:city nanjing xian km
“1331.5556”

georadius:根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。附近的人
所有数据都应该录入:china:city,才会让结果更加清晰!
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km #以110 30 这个经纬度为中心方圆1000km内的城市

  1. “chongqing”
  2. “shenzhen”
  3. “zhoukou”
  4. “nanjing”
    127.0.0.1:6379> GEORADIUS china:city 110 30 500 km #以110 30 这个经纬度为中心方圆500km内的城市
  5. “chongqing”
    127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withdist #以110 30 为中心方圆500km的城市及其相距的距离
    1. “chongqing”
    2. “336.6174”
      127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withcoord #以110 30 为中心方圆500km的城市及其坐标
    1. “chongqing”
      1. “106.5499994158744812”
      2. “29.56000053864853072”
        127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km withdist withcoord count 1 #以110 30 为中心方圆1000km的城市及其相距距离和坐标,只能显示一条
    1. “chongqing”
    2. “336.6174”
      1. “106.5499994158744812”
      2. “29.56000053864853072”
        127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km withdist withcoord count 2
        #以110 30 为中心方圆1000km的城市及其相距距离和坐标,只能显示两条
    1. “chongqing”
    2. “336.6174”
      1. “106.5499994158744812”
      2. “29.56000053864853072”
    1. “zhoukou”
    2. “594.4614”
      1. “114.65000241994857788”
      2. “33.59999880983598786”
        127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km withdist withcoord count 3
    1. “chongqing”
    2. “336.6174”
      1. “106.5499994158744812”
      2. “29.56000053864853072”
    1. “zhoukou”
    2. “594.4614”
      1. “114.65000241994857788”
      2. “33.59999880983598786”
    1. “nanjing”
    2. “869.1553”
      1. “118.80000203847885132”
      2. “32.06000108754685129”

georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。
#找出位于指定元素范围内的其它元素
127.0.0.1:6379> GEORADIUSBYMEMBER china:city nanjing 1000 km #找出位于nanjing 1000km的其它城市

  1. “zhoukou”
  2. “nanjing”
  3. “shanghai”
    127.0.0.1:6379> GEORADIUSBYMEMBER china:city zhoukou 500 km
  4. “zhoukou”
  5. “nanjing”

geohash:返回一个或多个位置对象的 geohash 值。
将二维的经纬度转换为一维的字符串,如果两个字符串越接近,那么距离越近
127.0.0.1:6379> geohash china:city chongqing zhoukou

  1. “wm7b0t5r6z0”
  2. “wtcx0utw4t0”

GEO的底层实现原理其实就是Zset!我们可以使用Zset命令来操作geo !
127.0.0.1:6379> zrange china:city 0 -1 #查看地图中全部的元素

  1. “chongqing”
  2. “shenzhen”
  3. “shanghai”
  4. “zhoukou”
  5. “nanjing”
  6. “xian”
    127.0.0.1:6379> zrem china:city xian #删除地图中指定元素
    (integer) 1
    127.0.0.1:6379> zrange china:city 0 -1
  7. “chongqing”
  8. “shenzhen”
  9. “shanghai”
  10. “zhoukou”
  11. “nanjing”

hyperloglog

什么是基数?
A{1,2,3,4,5,6,5,4}
B{1,3,5,7}
基数(不重复打的元素) = 3,可以接受误差

简介
Redis 2.8.9版本就更新了Hyperloglog数据结构!
Redis Hyperloglog基数统计的算法
优点:占用的内存是固定的,2^64不同的元素的技术,只需要12KB内存!如果从内存角度来比较的话Hyperloglog首选!

网页的UV(一个人访问一个网站多次,但是还是算作一个人!)
传统的方式,set保存用户的id,然后就可以统计set中的元素数量作为标准判断!
这个方式如果保存大量的用户id,就会比较麻烦!我们的目的是为了计数,而不是为了保存用户id;
0.81%错误率!统计UV任务,可以忽略不计的!
测试使用
127.0.0.1:6379> PFadd mykey a b c d e f g h i j #创建第一组元素mykey
(integer) 1
127.0.0.1:6379> PFCOUNT mykey #统计mykey元素的基数数量
(integer) 10
127.0.0.1:6379> PFadd mykey2 a b c d e b c n f #创建第一组元素mykey
(integer) 1
127.0.0.1:6379> PFCOUNT mykey2
(integer) 7
127.0.0.1:6379> PFMERGE mykey3 mykey mykey2 #合并mykey mykey2 => mykey3 并集
OK
127.0.0.1:6379> PFCOUNT mykey3 #查看并集的数量
(integer) 11

如果允许容错,那么一定可以使用Hyperloglog !
如果不允许容错,就使用set或者自己的数据类型即可 !

bitmap

位存储
统计用户信息,活跃,不活跃 !登录 未登录 ! 打卡 365天打卡 ! 两个状态的, 都可以使用 Bitmaps !
Bitmaps 位图 数据结构 ! 都是操作二进制位来进行记录,就只有0和1两个状态 !
365天 = 365bit 1字节=8bit
使用bitmaps来记录 周一到周日的打卡 !
周一:1 周二 : 0 周三: 0 …
127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 0
(integer) 0
127.0.0.1:6379> setbit sign 2 0
(integer) 0
127.0.0.1:6379> setbit sign 3 1
(integer) 0
127.0.0.1:6379> setbit sign 4 1
(integer) 0
127.0.0.1:6379> setbit sign 5 0
(integer) 0
127.0.0.1:6379> setbit sign 6 0
(integer) 0
查看某一天是否打卡
127.0.0.1:6379> getbit sign 4
(integer) 1
127.0.0.1:6379> getbit sign 5
(integer) 0
统计打卡的天数
127.0.0.1:6379> bitcount sign #统计这周的打卡记录,就可以看到是否全勤
(integer) 3

事务

Redis 事务本质: 一组命令的集合! 一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行!
一次性、顺序性、排他性!执行一些列的命令

Redis事务没有隔离级别的概念!
所有命令在事务中,并没有直接执行!只有发起执行命令的时候才会执行 !Exec
Redis单条命令是保证原子性的,但是事务不保证原子性!

redis的事务:
●开启事务(multi)
●命令入队(…)
●执行事务(exec)

正常执行事务
127.0.0.1:6379> multi 开启事务
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> get k3
QUEUED
127.0.0.1:6379> exec 执行事务

  1. OK
  2. OK
  3. “v2”
  4. (nil)

放弃事务
127.0.0.1:6379> multi 开启事务
OK
127.0.0.1:6379> set a1 b1
QUEUED
127.0.0.1:6379> set a2 b2
QUEUED
127.0.0.1:6379> set a3 b3
QUEUED
127.0.0.1:6379> DISCARD 取消事务
OK
127.0.0.1:6379> get a3 事务队列中的命令都不会被执行!
(nil)
127.0.0.1:6379> get a1
(nil)

编译型异常(代码有问题! 命令有错 !),事务中所有的命令都不会被执行!
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> getset k3 v3
QUEUED
127.0.0.1:6379> getset k4 错误的命令
(error) ERR wrong number of arguments for ‘getset’ command
127.0.0.1:6379> getset k5 v5
QUEUED
127.0.0.1:6379> exec 执行事务报错
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k5 所以命令都不会执行
(nil)

运行时异常(1/0),如果事务队列中存在与发行,那么执行命令的时候,其它命令是可以正常执行的,错误命令抛出异常
127.0.0.1:6379> set k1 “v1”
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr k1 会执行的时候失败
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> exec 虽然第一条命令报错了,但是依旧正常执行成功了!

  1. (error) ERR value is not an integer or out of range
  2. OK
  3. OK
  4. “v2”
    127.0.0.1:6379> get k3
    “v3”
    127.0.0.1:6379> get k1
    “v1”

监控!Watch (面试场问)
悲观锁:
●很悲观,认为什么时候都会出问题,无论做什么都会加锁!
乐观锁:
●很乐观,认为什么时候都不会出问题,所以不会上锁!更新数据的时候去判断一下,在此期间是否有人修改过这个数据
●获取version
●更新的时候比较version

Redis监视测试
watch 监视对象当前值, 如果事务执行之间值被其它线程改变,则执行失败,此时需要unwatch,然后重新watch
正常执行成功
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money 监视money对象
OK
127.0.0.1:6379> multi 事务正常结束,数据期间没有发生变动,这个时候就正常执行成功
OK
127.0.0.1:6379> DECRBY money 20
QUEUED
127.0.0.1:6379> INCRBY out 20
QUEUED
127.0.0.1:6379> exec

  1. (integer) 80
  2. (integer) 20

测试多线程修改值,使用watch可以当做redis的乐观锁操作
127.0.0.1:6379> watch money 监视money对象
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> DECRBY money 20
QUEUED
127.0.0.1:6379> INCRBY out 20
QUEUED
127.0.0.1:6379> exec 执行之前,另外一个线程修改了值,这个时候,会导致事务执行失败!
(nil)

什么是Jedis 是Redis官方推荐的java连接开发工具!使用java操作Redis中间件!如果你要使用java操作redis,那么一定要对jedis十分的熟悉!

慢慢来会很快!

首先maven中导入地址

<dependencies><!-- https://mvnrepository.com/artifact/redis.clients/jedis --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.2.0</version></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.75</version></dependency></dependencies>

●连接数据库
●操作命令
●断开连接!

public static void main(String[] args) {
//1. new Jedis 对象即可
Jedis jedis = new Jedis(“127.0.0.1”,6379);
//jedis所以的命令就是我们之前学习的所有命令!所以之前的指令学习很重要!
System.out.println(jedis.ping());
}

输出:

常用API
String get set
List push rem
Set add
Hash hset
Zset zadd

SpringBoot操作数据: spring-data,jpa,jdbc mongodb redis !
SpringData 也是和SpringBoot齐名的项目 !
说明: 在SpringBoot2.0 以后,原来使用的jedis 被替换成了lettuce!
jedis:采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用jedis pool连接池 ! 更像BIO 模式
lettuce:采用netty,实例可以在多个线程中进行共享,不存在线程不安全的情况!可以减少线程数据了,更像NIO 模式

整合测试一下
1.导入依赖

org.springframework.boot
spring-boot-starter-data-redis

2.配置连接
配置redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
3.测试!
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {

    //redisTemplate//opsForValue 操作字符串  类似String//opsForList 操作list 类似List//opsForSet//opsForHash//opsForZset//opsForGeo//opsForHyperLogLog//除了基本的操作,我们常用的方法都可以直接通过redisTemplate操作,比如事务,和基本的CRUD//获取redis的连接对象

// RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
// connection.flushDb();;
// connection.flushAll();

    redisTemplate.opsForValue().set("mykey","xiaoxue");System.out.println(redisTemplate.opsForValue().get("mykey"));
}


需要序列化pojo类中的对象,实现serializable接口,才能执行成功

可以通过编写RedisUtill类来简化代码书写

所以的redis操作,其实对于java开发人员来说,十分的简单,更重要的是理解redis的思想和每一种数据结构的用处和作用场景!

Redis.conf详解

启动的时候,就通过配置文件来启动!


网络
bin 127.0.0.1 #绑定的ip
protected-mode yes #保护模式
port 6379 #端口设置

通用GENERAL
demonize yes # 以守护进程的方式运行,默认是no,我们需要自己开启为yes
pidfile /var/run/redis_6379.pid #如果以后台的方式运行,我们就需要指定一个pid文件!

快照
持久化,在规定的时间内,执行了多少次操作,则会持久化到文件,rdb、aof

redis是内存数据库,如果没有持久化,那么数据断电即失 !

#如果900秒内,如果至少有一个1个key进行了修改,我们即进行持久化操作
save 900 1
#如果300s内,如果至少10个key进行了修改,我们即进行持久化操作
save 300 10
#如果60s内, 如果至少10000个key进行了操作,我们即进行持久化操作
save 60 10000
#我们之后学习持久化,会自己定义这个测试!

stop-writes-on-bgsave-error yes #持久化如果出错,是否还需要继续工作!

rdbcompression yes #是否压缩rdb文件,需要消耗一些cpu资源!

rdbchecksum yes #保存rdb文件的时候,进行错误的检查校验

dir ./ # rdb 文件保存的目录

REPLICATION复制,我们后面讲解主从复制的时候再进行讲解

SECURITY安全

可以在这里设置redis的密码,默认是没有密码!
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> clear
127.0.0.1:6379> config get requirepass # 获取redis的密码

  1. “requirepass”
  2. “”
    127.0.0.1:6379> config set requirepass “123456”# 设置redis的密码
    OK
    127.0.0.1:6379> config get requirepass**# 发现所有的命令都没有权限了**
    (error) NOAUTH Authentication required.
    127.0.0.1:6379> auth 123456 # 使用密码登录!
    ok
    127.0.0.1:6379> config get requirepass
  3. “requirepass”
  4. “123456”

限制CLIENTS
maxclients 10000 设置能连接上redis的最大客户端的数量
maxmemory redis 配置最大的内存容量
maxmemory-policy noeviction 内存到达上限之后的处理策略
#移除一些过期的key
#报错
#…

maxmemory-policy 六种方式
1、volatile-lru:只对设置了过期时间的key进行LRU(默认值)
2、allkeys-lru : 删除lru算法的key
3、volatile-random:随机删除即将过期key
4、allkeys-random:随机删除
5、volatile-ttl : 删除即将过期的
6、noeviction : 永不过期,返回错误

APPEND ONLY模式 aof配置
appendonly no # 默认时不开启aof模式的,默认是使用rdb方式持久化的,在大部分所有情况下,rdb完全够用!
qppendfilename “appendonly.aof” # 持久化的文件的名字

appendfsync always # 每次修改都会sync。消耗性能

appendfsync everysec # 每秒执行一次synv,可能会丢失这ls的数据!

appendfsynv no #不执行sync,这个时候操作系统自己同步数据,速度最快!

具体的配置,在Redis持久化详细讲解

Redis持久化

面试和工作,持久化都是重点!

Redis是内存数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会小时。所以Redis提供了持久化功能!
RDB (Redis DataBase)
在主从复制中,rdb就是备用了!从机上面!

在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里。

Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的。这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效,RDB的缺点就是最后一次持久化后的数据可能丢失。我们默认的就是RDB,一般情况下不需要修改这个配置!

有时候在生产环境我们会将这个文件进行备份 !

rdb保存的文件时dump.rdb 都是在我们的配置文件快照中进行配置的!

触发机制
1.save的规则满足的情况下,会自动触发rdb规则
2.执行flushall命令,也会触发我们的rdb规则
3.推出redis,也会产生rdb文件 !
备份就自动生成一个dump.rdb

如果恢复rdb文件!
1.只需要将rdb文件放在我们的redis启动目录就可以了,reids启动的时候会自动检查dump.rdb恢复其中的数据!
2.查看需要存放的位置
127.0.0.1:6379>config get dir

  1. “dir”
  2. “/usr/local/bin” #如果在这个目录下存在dump.rdb文件,启动就会自动恢复其中的数据
    几乎他自己默认的配置就够用了,但是我们还是需要学习
    优点
    1.适合大规模的数据恢复!
    2.对数据的完整性要求不高!
    缺点
    1.需要一定的时间间隔进程操作!如果redis意外宕机了,这个最后一次修改数据就没有了
    2.fork进程的时候,会占用一定的内存空间

AOF(Append Only File)
将所有的命令都记录下来,history,恢复的时候就把这个文件全部执行一遍 !



以日志的形式来记录每个写操作,将Redis执行过的所有指令记录下来(该操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作

*Aof保存的是appendonly.aof 文件 *

append

默认是不开启的,我们需要手动进行配置!我们只需要将appendonly改为yes就开启了aof!
重启redis,就生效了!
如果这个aof文件有错误,这时候redis是启动不起来的,我们需要修复这个aof文件
redis给我们提供给了一个工具 redis-check-aof

如果文件修复成功,重启就可以直接恢复了

重写规则说明
aof默认就是文件的无限追加,文件会越来越大!

如果aof文件大于64m,太大了!fork一个新的进程来讲我们的文件进行重写!

优点和缺点

appendonly no # 默认时不开启aof模式的,默认是使用rdb方式持久化的,在大部分所有情况下,rdb完全够用!
qppendfilename “appendonly.aof” # 持久化的文件的名字

appendfsync always # 每次修改都会sync。消耗性能
appendfsync everysec # 每秒执行一次synv,可能会丢失这ls的数据!
appendfsynv no #不执行sync,这个时候操作系统自己同步数据,速度最快!

优点:
1.每一次修改都同步,文件的完整性会更好!
2.每秒同步一次,可能会丢失一秒的数据
3.从不同步,效率最高的!
缺点:
1.相对于数据文件来说,aof远远大于rdb,修复速度也比rdb慢!
2.Aof运行效率也要比rdb慢,所以我们redis默认的配置就是rdb持久化!

Redis发布订阅

Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
Redis客户端可以订阅任意数量的频道。
订阅/发布消息图:
第一个:消息发送者,第二个:频道 第三个:消息订阅者

下图展示了频道channel1,以及订阅这个频道的三个客户端— —
client2、client5和client之间的关系:

当有消息通过PUBLISH命令发送给频道channel1时,这个消息就会被发送给订阅它的三个客户端:

命令

这些命令被广泛用于构建即时通信应用,比如网络聊天室(chatroom)和实时广播,实时提醒等。

测试
订阅端
127.0.0.1:6379> subscribe yuxiaoxue
Reading messages… (press Ctrl-C to quit)

  1. “subscribe”
  2. “yuxiaoxue”
  3. (integer) 1
    等待读取推送的信息
  4. “message” # 消息
  5. “yuxiaoxue” #哪个频道
  6. “hello beautiful girl” # 消息的具体内容
  7. “message”
  8. “yuxiaoxue”
  9. “hello redis”
    发送端
    127.0.0.1:6379> publish yuxiaoxue “hello beautiful girl” # 发布者发布信息到频道!
    (integer) 1
    127.0.0.1:6379> publish yuxiaoxue “hello redis” # 发布者发布信息到频道!
    (integer) 1

原理

使用场景:
1.实时消息系统!
2.实时聊天!(频道当做聊天室,将信息回显给所有人即可!)
3.订阅,关注系统都是可以的!
稍微复杂的场景我们就会使用 消息中间件MQ()

Redis主从复制

概念
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器,前者称为主节点(master/leader),后者称为从节点(slave/follwer);数据的复制是单向的,只能由主节点到从节点,Master以写为主,Slave以读为主。

默认情况下,每台Redis都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。

主从复制的作用主要包括:

1.数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
2.故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
3.负载均衡:在主从复制的基础上,配合读写分离,可以由主机诶单提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载:尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
4.高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。

一般来说,要将Redis运用于工程项目中,只使用一台Redis是万万不能的(宕机),原因如下:
1.从结构上,单个Redsi服务器会发生单点故障,并且一台服务器需要处理所有的负载均衡,压力较大;
2.从容量上,单个Redis服务器内存容量有限,就算一台Redis服务器内存容量为256G,也不能将所有的内存作Redis存储内存,一般来说,单台Redis最大使用内存不应该超过20G

电商网站上的商品,一般都是一次上传,无数次浏览的,说专业点也就是“多读少写”。
对于这种场景,我们可以使用如下这种架构:

主从复制,读写分离!80%的情况下都是在进行读操作!减缓服务器的压力!架构中经常使用!一主二从!
只要在公司中,主从复制就是就是必须要使用的,因为在真实的项目中不可能单机使用Redis!

环境配置
只配置从库,不用配置主库!

127.0.0.1:6379> info replication #查看当前库的信息

Replication

role:master 角色 master
connected_slaves:0 #没有从机
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

复制3个配置文件,然后修改对应的信息
1.端口
2.pid名字
3.log文件名字
4.dump.rdb名字
修改完毕之后,启动我们的3个redis服务器,可以通过进程信息查看!

一主二从
默认情况下,每台Redis服务器都是主节点;我们一般情况下只用配置从机就好了!
认老大!一主(79)二从(80、81)


如果两个都配置完,就有两个从机

真实的主从配置应该在配置文件中配置,这样的话是永久的,我们这里使用的是命令,暂时的!

细节

主机可以写,从机不能写只能读!主机中的所有信息和数据,都会被从机自动保存 !
主机写:

从机只能读取内容

测试:主机断开连接,从机依旧连接到主机的,但是没有写操作,这个时候,主机如果回来了,从机依旧可以直接获取到主机写的信息!
如果是命令行,来配置的主从,如果重启了,就会变回主机!只要变回从机,立马就会从主机中获取值!

复制原理

如果没有老大了,这个时候能不能选择一个老大出来呢?手动!

谋朝篡位
如果主机断开了连接,我们可以用 SLAVEOF NO ONE命令让自己变成主机!其它的节点就可以手动连接到最新的这个主节点(手动) !如果这个时候老大修复了,只能重新配置

哨兵模式
(自动选取老大的模式)

概念

主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费时费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。Redis从2.8开始正式提供了Sentinel(哨兵)架构来解决这个问题。

谋朝篡位的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库

哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。

这里的哨兵有两个作用
●通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。
●当哨兵检测到master宕机,会自动将Slave切换成master,然后通过发布订阅模式通知其它的从服务器,修改配置文件,让他们切换主机。

然而一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控,各个哨兵之间还会进行监控,这样就形成了多哨兵模式。

假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover过程,仅仅是哨兵1主观的认为服务器不可用,这个现象成为主观下线。当后面的哨兵也检测到主服务器不可用,并且数量打到一定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行failover【故障转移】操作。切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程成为客观下线

测试
我们目前的状态是一主二从
1、配置值哨兵配置文件sentinel.conf

后面的这个数字1,代表主机挂了,slave投票看让谁接替成为主机,票数最多的,就会成为主机!
2、启动哨兵 !

如果Master(主机)节点断开了,这个时候就会从从机中随机选择一个服务器!(这里面有一个投票算法!)

哨兵日志

如果主机此时回来了,只能归并到新的主机下,当做从机,这就是哨兵模式的规则!

哨兵模式
优点:
1、哨兵集群,基于主从复制模式,所以的主从配置优点,它全有
2、主从可以切换,故障可以转换,系统的可用性就会更好
3、哨兵模式就是主从模式的升级,手动到自动,更加健壮!
缺点:
1、Redis不好在线扩容的,集群容量一旦达到上线,在线扩容就十分麻烦!
2、实现哨兵模式的配置其实是很麻烦的,里面有很多选择!

哨兵模式的全部配置

社会目前程序员饱和(初级和中级)、高级程序员重金难求!(提升自己)

Redis缓存穿透和雪崩

缓存穿透 查不到

缓存击穿 量太大,缓存过期

布隆过滤器

缓存空对象
当存储层不命中后,即是返回的空对象也将其缓存起来,同时会设置一个过期时间,之后再访问这个数据将会从缓存中获取,保护了后端数据源;

一、缓存处理流程

  前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓存,并返回结果,数据库也没取到,那直接返回空结果。

二、缓存穿透(查不到导致)

   描述:缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。

  解决方案:

接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击

三、缓存击穿(量太大,缓存过期)

概述

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力

解决方案

1.设置热点数据永远不过期。
2.加互斥锁
分布式锁:使用分布式锁,保证对于每个key同时只有一个线程去查询后端服务,其他线程没有获得分布式锁的权限,因此只需要等待即可。这种方式将高并发的压力转移到了分布式锁,因此对分布式锁的考验很大。

互斥锁参考代码如下:

      说明:1)缓存中有数据,直接走上述代码13行后就返回结果了2)缓存中没有数据,第1个进入的线程,获取锁并从数据库去取数据,没释放锁之前,其他并行进入的线程会等待100ms,再重新去缓存取数据。这样就防止都去数据库重复取数据,重复往缓存中更新数据情况出现。3)当然这是简化处理,理论上如果能根据key值加锁就更好了,就是线程A从数据库取key1的数据并不妨碍线程B取key2的数据,上面代码明显做不到这点。

四、缓存雪崩


  描述:缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决方案:
缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。
设置热点数据永远不过期。

小结

声明:此博客是在听讲狂神Redis课程总结,然后自己整理所得,仅供参考!!!如想学习,欢迎b站搜索 ‘遇见狂神说’*

狂神 redis笔记 docker相关推荐

  1. 狂神redis笔记_狂神说redis笔记(三)

    八.Redis.conf 容量单位不区分大小写,G和GB有区别 可以使用 include 组合多个配置问题 网络配置 日志 # 日志 # Specify the server verbosity le ...

  2. 狂神redis笔记_狂神说redis笔记(一)

    一.Nosql概述 1.单机Mysql时代 90年代,一个网站的访问量一般不会太大,单个数据库完全够用.随着用户增多,网站出现以下问题: 数据量增加到一定程度,单机数据库就放不下了 数据的索引(B+ ...

  3. 狂神说Redis笔记

    以下是狂神Redis笔记,个人觉得总结的很好,故收藏一下,日后再总结一下自己的笔记 ⭐学习时间2022.1.4-2022.1.6 一.Nosql概述 为什么使用Nosql 1.单机Mysql时代 90 ...

  4. 狂神说--docker学习笔记-docker安装,常用命令,以及使用

    狂神说bilibili视频地址:https://www.bilibili.com/video/BV1og4y1q7M4?p=1 1. Docker概述 1.1 Docker为什么出现? 大家经常做一款 ...

  5. Kubernetes CKA认证运维工程师笔记-Docker快速入门

    Kubernetes CKA认证运维工程师笔记-Docker快速入门 1. Docker 概念与安装 1.1 Docker 是什么 1.2 Docker 基本组成 1.3 版本与支持平台 1.4 Do ...

  6. MySQL(狂神说笔记)

    MySQL(狂神说笔记) 1.初始数据库 1.1为什么学习数据库? 1.岗位需求 2.现在的世界,大数据时代,得数据库者得天下. 3.被迫需求: 存数据 4.数据库是所有软件体系中最核心的存在: DB ...

  7. ElasticSearch(狂神说笔记)

    ElasticSearch(狂神说笔记) ES安装及head插件安装 声明:JDK 1.8以上,最低要求!ElasticSearch 客户端.界面工具! Java 开发,ElasticSearch的版 ...

  8. RabbitMQ狂神说笔记(RabbitMQ B站狂神说笔记、KuangStudy、学相伴飞哥)

    一. 引用文章 RabbitMQ狂神说笔记(B站狂神说笔记.KuangStudy.学相伴飞哥) RabbitMQ狂神说笔记(B站狂神说笔记.KuangStudy.学相伴飞哥)百度云盘地址,提取码:07 ...

  9. 黑马Redis笔记高级篇 | 多级缓存

    黑马Redis笔记高级篇 | 多级缓存(黑马教程云服务器踩坑记录) 1.JVM进程缓存(tomcat服务内部) 1.1 导入商品案例 1.2 初识Caffeine 1.3 实现进程缓存 2.Lua语法 ...

  10. homeassistant mysql_HomeAssistant学习笔记docker安装的ha更换数据库

    HomeAssistant学习笔记docker安装的ha更换数据库 用了一段时间之后发现日志和历史打开的速度越来越慢,在论坛里查了半天发现是因为HA官方所用数据库导致,官方也给出了相关文档,https ...

最新文章

  1. plotly可视化绘制多子图(subplots)并自定义坐标轴
  2. 远程桌面网关Apache Guacamole 发布1.0.0版本\n
  3. 牛客 - 骚区间(线段树+思维)
  4. n2n内网穿透打洞部署全过程 + nginx公网端口映射
  5. Vagrant 构建 Linux 开发环境
  6. 《Python Cookbook 3rd》笔记(5.15):打印不合法的文件名
  7. CSS3-新增属性选择器
  8. CDOJ--1850
  9. python anaconda和pycharm_Python 、Pycharm、Anaconda三者的区别与联系、安装过程及注意事项...
  10. php实现关键字搜索mysql数据_PHP实现多个关键词搜索查询功能示例
  11. 求一个容器的最值的索引_初中数学:一道几何好题,学会“胡不归问题”动点最值解题方法...
  12. vue微信支付回到原界面不执行mounted里的内容
  13. pandas的两种数据类型:Series和DataFrame
  14. 综合应用WPF/WCF/WF/LINQ之二十九:代码生成器之DBMLToCode
  15. 【三维路径规划】基于matlab A_star算法无人机三维路径规划【含Matlab源码 1387期】
  16. 计算机四级网络工程师题库及详细知识点大全
  17. 学习markdown
  18. 你了解资金盘吗?那孪生兄弟产品盘你知道吗?
  19. 看完《百家讲坛》之后的108个经典“留言”
  20. one 主格 复数 宾格_主格和宾格的复数形式到底怎么写请说出答案

热门文章

  1. vtd和vt的区别_vtvi和v的区别是什么?
  2. 固定不动的层(兼容IE6)
  3. LTE学习-信道均衡(ZF)
  4. 2寸照片尺寸大小是多少,两寸照片多大?
  5. 怎样清理软件卸载残留文件和系统垃圾
  6. software_reporter_tool 进程关闭的优雅法子
  7. linux一款和beyond compare功能相仿的软件,meld
  8. maven-publish插件的使用笔记
  9. 1g等于多少mb计算机网络,1g等于多少mb 硬盘容量详细介绍
  10. pinterest,图片网站的传奇