一,前言
(一)磁盘和带宽区别:
维度 | 磁盘 | 带宽 |
---|---|---|
寻址 | ms | G/M |
带宽 | ns | 很大 |
秒 > 毫秒 > 微妙 > 纳秒 磁盘比内存上的寻址满了10W倍
(二)关系型数据库建表必须给出schema:
类型:字节宽度
存储:倾向于行级存储
例:10个宽度,只存了一个值,其他位置也要占位,增删改不用移动位置,直接覆盖即可。
数据库的B+T在内存中,数据在磁盘
索引是什么?
举个栗子:评价一个外卖小哥的投递速度,在交通工具相同的前提下,怎么在一个小区内找到对应人?在不清楚楼号位置,楼层标记的情况下,需要挨个去看是哪个楼号,这个就是寻址慢远原因。但如果他知道楼号和层级分布,直接定位到对应的楼层,只需要查看一下该楼层内客户的门牌号即可。记得有个小哥说,我看名字就知道这个人在什么位置,这个就是放在内存中的索引。
(三)数据库:表很大,性能是否下降?
如果表有索引,增删改必然会变慢
查询速度考虑两个因素,查询命中的数量受带宽的影响
1,1个或者少量查询依然会很快;
2,并发大的时候会受到硬盘,带宽影响速度。
(四)为什么会出现redis
内存级数据库成本大
SAP HANA内存级别的关系型数据库2T 2个亿
数据和磁盘体积不一样:索引会占用内存,数据也可以有压缩的策略。
在高额成本和对速度的要求上,折中方案 : 缓存
memcached , redis
(五)redis.cn 官网介绍
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。
Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
(六)都是key,value,为什么redis能取代比他早出的memcached ?
redis可以根据用户要获得JSON中的某一小部分元素,可以只取其一小部分并返回。
memcached需要全量地返回整个JSON而不能去解析它的一部分,需要客户端自己去解析。memcached的性能损耗会在IO以及客户端数据的解析上。
重要的不是类型,重要的是Redis Server对每种数据类型都实现了自己的方法(函数)。
计算向数据移动。
memcached 的value 没有类型,而redis的value 类型降低了处理返回数据的成本。
二,原理
(一)为什么单进程,单线程,单实例并发很多的请求,如何变得很快?
epoll 内核提供的系统级调用
用系统调用遍历请求,看谁有数据,处理谁的请求。
内存比IO快
(二)IO-内核的发展
1,BIO
数据包没有到得时候 ,read是阻塞的 ,cpu并没有时刻处理 ,资源浪费。
每次连接抛出一个线程/进程。
2,NIO
内核发生了变化
轮询循环连接,查看那个有数据就处理那个。
用户进程轮询1000次kernel ,成本太大。
JVM:一个线程的成本,栈的大小1MB。
1,线程多了调度成本CPU增加;
2,内存成本。
3,多路复用的NIO
增加了系统调用select,1000个文件描述符一次性发送给内核,把用户轮询的事情放在内核中完成。
1000次连接复用一次内核连接,1000个文件描述符调用select一次性传给内核,返回一个数据,但是线程/进程自己得完成拷贝数据的过程。
同步非阻塞。
4,共享空间的NIO
减少拷贝,共享空间(mmap)
线程/进程调用create epfd , epoll启动共享空间(mmap),把1000次连接放到红黑树内,把可以使用的放到链表中,使用read调用。
5,零拷贝
数据先到 kernel(buffer),read到用户空间程序中,然后在write在拷贝回来kernel(buffer),写到文件中。