redis内核(每周分享一个技术)

1.单线程为什么那么快

①redis是一个内存型的k-v形式的数据库,所有的数据都是存储在内存上中,读取,写入速度快,阈值是10毫秒

②redis的io是异步的,由redis server 分给epoll去处理(比如过期,删除),尽量避免在ridis中存入大key,超过500k就算是大key,一般读取大key

③redis基本没有日志,唯一写入是aof,类似binlog,去掉不必要的日志

2.Key-Value

①key的内部编码:在内存中已那种编码去存储:

String中是(Raw, init,Embstr),Raw也被称为原始string,如果数据用Raw格式存储,他就是原始的,磁盘有一种模式就是Raw模式,也被称为裸盘模式,在这个模式下,数据以原始的形式存储,你可以直接读取它。

INT格式,意味着它是一个整型数字。INT一般是整数,这个字符串是一个整形字符串,长度不是特别长的一个整形字符串,整形字符串整数数字,你是一个整数数字,我就会以INT形式存储。(用一个八位编码的整数就是init,long double 就是embstr存储)

EMBSTR会以它存储,就是当数值,就当是一串整形。(只读编码)

3.Memcached和redis的区别

Memcached:只能存储KV、没有持久化机制、不支持主从复制、是多线程

redis:数据类型丰富、支持多种编程语言、功能丰富(持久化机制,内存淘汰机制,事务,发布订阅,pipline,lua),支持集群,分布式

4.Hash与String的主要区别

①把所有相关的值都聚集到一个Key中,节省内存空间

②只使用一个Key,减少Key冲突

③当需要批量获取值的时候,只需要使用一个命令,减少内存io/cpu的消耗

④hash不适合的场景:Field不能单独设置过期时间,需要考虑数据量分布的问题

5.二进制SDS安全

redis3.2以前

struct sdshdr{
     int len;//buf数组中已经使用的字节的数量,也就是SDS字符串长度
        int  free;//buf数组中未使用的字节的数量
        char buf[];//字节数组,字符串就保存在这里面
};

3.2以后

struct_attribute_((_packed_))sdshdr8{
    uint8_t len;//当前字节数组的长度
    uint8_t alloc;//当前字节数组总共分配的内存大小
    uimt8_t flag;//当前字节数组的属性,用来标识到底是sdshdr8还是sdshdr16等
    char buf[]; //字符串真正的值
}

特点:

①不用担心内存溢出问题,如果需要会对SDS进行扩容

②获取字符串长度时间复杂度0(1),定义了属性

③通过空间预分配和惰性预分配,防止多次重分配

④判断是否结束的标志是len属性

6.RESP通信协议

序列化协议,容易实现,解析快,可读性强。把命令,长度和参数用/r/n连接起来

package redis;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
 
public class RespTest {
 
    private Socket socket;
    private OutputStream write;
    private InputStream read;
 
    public RespTest(String host, int port) throws IOException {
        socket = new Socket(host, port);
        write = socket.getOutputStream();
        read = socket.getInputStream();
    }
 
    /**
     * 实现了set方法
     * @param key
     * @param val
     * @throws IOException
     */
    public void set(String key, String val) throws IOException {
        StringBuffer sb = new StringBuffer();
        // 代表3个参数(set key value)
        sb.append("*3").append("\r\n");
        // 第一个参数(set)的长度
        sb.append("$3").append("\r\n");
        // 第一个参数的内容
        sb.append("SET").append("\r\n");
 
        // 第二个参数key的长度(不定,动态获取)
        sb.append("$").append(key.getBytes().length).append("\r\n");
        // 第二个参数key的内容
        sb.append(key).append("\r\n");
        // 第三个参数value的长度(不定,动态获取)
        sb.append("$").append(v
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值