Redis初识-1
一、特性之速度快
- 数据在内存中(主要的)
- 用c语言实现
- 采用单线程
单线程本身很慢啊?
- 纯内存(主因)
- 非阻塞IO
- 避免线程切换产生的消耗
官方回答:因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了(毕竟采用多线程会有很多麻烦!)。
二、特性之持久化
对数据的更新将异步的保存在磁盘上。
三、特性之数据结构
- String
- Hash
- List
- Sets
- Sorted Sets
- 高级的如位图(BitMaps),HyperLogLog(超小内存唯一值计数),GEO(地理信息定位)
String
key和value都是字符串
场景:缓存,计数器,分布式锁等等
常用命令:get、set、del (对value获取,修改,删除键值对)
实战场景:记录网站每个用户个人主页的访问量。分布式id生成器。
hash
key+value,其中value是一个hashmap。或者说可以把value再分成field+value即hashmap的键和值。field是不能相同的。
常用命令:hget、hset、dhel
实战场景:记录网站每个用户个人主页的访问量。和String区别在于,之前只能是user_count+count(count),而现在可以分离,user+count+count(num),并且还可以添加其他的功能到map中的field中。
list
key+value ,value是一个链表。双端链表。
实战场景:微博你关注的人,按照微博的发布顺序给你展示出来。最新的在上面,则头插。
注:可以实现栈,队列,消息队列等功能。
set 无序不重复
实战:set类型唯一的特点使得其适合用于存储好友/关注/粉丝/感兴趣的人集合,集合中的元素数量可能很多,每次全部取出来成本不小,set类型提供了一些很实用的命令用于直接操作这些集合。实现方式是key是用户,value是关注的人,然后两个value的容器进行对比,最后筛选出共同关注的人。还可以随机展示,通常,app首页的展示区域有限,但是又不能总是展示固定的内容,一种做法是先确定一批需要展示的内容,再从中随机获取。
注:类比于java中的set,就和hashset类似。只要达到去重的目的即可。
zset 有序
key+value,其中value可以细分成score+value。通过score实现有序。
实战:排行榜
四、通用命令
- keys 遍历出所有的key 一般使用比较少,因为是时间复杂度是O(n)的命令。
- dbsize 计算key的总数 O(1)
- exists (key) 检测key是否存在 O(1)
- del (key) 删除指定的Key-value O(1)
- expire 指定一个过期时间 O(1)
- ttl (key) 查看Key剩余时间 O(1)
- perisist 去掉key的过期时间 O(1)
- type (key) 返回key的类型 O(1)
五、比较String和hash
对一个user表的信息使用String建表。
String方式1:
String方式2:
hash实现
以上区别在于
说明:String1每次修改都是把所有数据取出,然后改掉相应的,再全部写回,因为一个user只有一个键值。而String2将user每个属性都变成键值对。因此修改时直接取对应的键值即可。但是key分散在内存中,且有多个键值队,内存占用大,而hash就解决了这些问题。ttl是控制过期时间,因为只能设置键的,field的需要单独去设计。比如置为null之类的。
六、其他功能
慢查询
下图表示Redis的基本工作流程。
两个配置
当一个命令想看看是否是慢查询时,会被放进一个队列,这个队列是一个先进先出的队列,有固定长度,保持在内存中。
- showlog-log-slower-than 慢查询阈值(微秒) 等于0则记录所有命令。即将所有命令加入到慢查询的队列中,进行观察。默认10ms,通常设置1ms.
- showlog-max-len 慢查询队列(list)的长度。默认128,通常1000左右
pipeline 流水线
注:这里的1条命令是指每次执行的数量。
发布订阅
Kafka中,也就是消息队列中,有两种方式,一个是点对点,一个是发布订阅,所以这个是一个包含关系。
Bitmap 位图
主要就是节约空间。
说明:比如用户一年的签到记录,签了是 1,没签是 0,要记录 365 天。如果使用普通的 key/value,每个用户要记录 365个(因为我要知道,365天中,哪几天签到,所以需要最多365个数据),365个整型int,当用户上亿的时候,需要的存储空间是惊人的。为了解决这个问题,Redis 提供了位图数据结构,这样每天的签到记录只占据一个位,365 天就是 365 个位,46 个字节 (一个字节有8位) 就可以完全容纳下,这就大大节约了存储空间。
示例:
说明:1亿用户,5千万今天访问,为了记录访问量,可以用set记录今天访问的id,假设id用的整型即32位。也可以用1位的位图标记某个id是否访问。因此就是1乘1亿的内存。另一边是32乘5千万,谁的空间少简而易见。而假设访问量只有10万,则10万乘32位又明显比位图要优了。
因为bitmap其实就是一个string?这句话应该怎么理解。里面的位数组的元素是字符串?
HyperLogLog
极小空间完成独立数量的统计。
