怎么做网站的外部连接您在工信部门备案网站获取的icp备案号
怎么做网站的外部连接,您在工信部门备案网站获取的icp备案号,电商 网站开发 哪个好,专门做娱乐场所的设计网站String编码转换底层原理
String对象为什么把大于39字节或者44字节的字符串编码为raw#xff0c;小于的时候编码为embstr?
在Redis3.2以前的版本中,SDS作为字符串类型中存储字符串内容的结构#xff0c;源码如下#xff1a;
3.2版本SDS结构
struct sdshdr {// 记录buf数…String编码转换底层原理
String对象为什么把大于39字节或者44字节的字符串编码为raw小于的时候编码为embstr?
在Redis3.2以前的版本中,SDS作为字符串类型中存储字符串内容的结构源码如下
3.2版本SDS结构
struct sdshdr {// 记录buf数组中已使用字节的数量// 等于SDS保存字符串的长度 4byteint len;// 记录buf数组中未使用字节的数量 4byteint free;// 字节数组用于保存字符串 字节\0结尾的字符串占用了1bytechar buf[];
}Redis对象头
一个字符串对象不仅仅包含SDS结构还包含了RedisObject(Redis对象头)这时每个Redis对象都要携带的一种结构跟Java对象类似Java对象也有相应的对象头它的结构如下
// Redis对象
typedef struct redisObject {// 类型 4bits; 即【String、List、Hash、Set、Zset】中的一个unsigned type:4// 编码方式 4 bits, encoding表示对象底层所使用的编码unsigned encoding:4;// LRU时间(相对于server.lrulock) 24bits;unsigned lru:24;// 引用计数 Redis里面的数据可以通过引用计数进行共享 32bitsint refcount;// 指向对象的值 64bitvoid* ptr;
} robj; // 16bytes操作系统中的内存分配
由于操作系统使用jmalloc和tmalloc进行内存的分配而内存分配的单位都是2的N次方所以是2,4,8,16,32,64,如果Redis采取32字节分配的化那么32-16(RedisObject)-9(3.2版本的SDS)7,相当于可使用字节数为7字节Redis认为太过于小了所以Redis采取分配的是64字节即64-2539。
SDS结构优化
在Redis之后的版本中为了进一步优化字符串对象在一次操作系统的内存分配中扩大可使用的空间又将sdshdr分为了sdshdr5、sdshdr8、sdshdr16、sdshdr32、sdshdr64结构如下
struct __attribute__ ((__packed__)) sdshdr5 {unsigned char flags; /* 3 lsb of type, and 5 msb of string length */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {uint8_t len; /* used */uint8_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr16 {uint16_t len; /* used */uint16_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {uint32_t len; /* used */uint32_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {uint64_t len; /* used */uint64_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};
// 一些变量的定义
#define SDS_TYPE_5 0
#define SDS_TYPE_8 1
#define SDS_TYPE_16 2
#define SDS_TYPE_32 3
#define SDS_TYPE_64 4结构示例图
sdshdr5的结构如图 sdshdr8的结构如图
疑惑解答
有人可能会问既然分出来这么多的结构如果用sdshdr5的结构那么64-16-1-146个字节跟平常说的44个字节不一样如果我们用sdshdr5的结构那么这个结构的flags中只有5个bit可以让我们使用 表示的空间地址就是2^532个长度表示的空间太小了所以我们得用sdshdr8的结构那么可以表示的空间地址 将会是2^8256但实际上在Redis内部中键是使用sdshdr5的结构因为键不大可能会更新而值会经常更新所以干脆直接sdshdr8来表示值对象
Redis6.0新特性
多线程
概述
redis6.0提供了多线程的支持redis6以前的版本严格来说也是多线程只不过执行用户命令的请求是单线程模型还有一些线程用来执行后台任务比如unlink删除大keyrdb持久化等
redis6.0提供了多线程的读写IO,但是最终执行用户命令的线程依然是单线程的这样就没有多线程数据的竞争关系依然很高效
线程模型 redis6.0以前线程执行模式如下操作再一个线程中执行完成 redis6.0线程执行模式:
参数配置
可以通过如下参数配置多线程模型:
io-threads 4 // 这里说 有三个IO线程还有一个线程是main线程main线程负责IO读写和命令执行操作默认情况下如上配置有三个IO线程这三个IO线程只会执行IO中的write操作也就是说read和命令执行都由main线程执行最后多线程讲数据写回客户端。 开启了如下参数:
io-threadas-do-reads yes // 将支持IO线程执行 读写任务Client side caching(客户端缓存)
概述
redis6提供了服务端追踪key的变化客户端缓存数据的特性这需要客户端实现
执行流程
当客户端访问某个key时服务端将记录key和client客户端拿到数据后进行客户端缓存这时当key再次被访问时key将被直接返回避免了与redis服务器的再次交互节省服务端资源当数据被其他请求修改时服务端将主动通知客户端失效的key客户端进行本地失效下次请求时重新获取最新数据目前只有lettuce对其进行了支持:
代码示例
依赖导入
dependency
groupIdio.lettuce/groupId
artifactIdlettuce‐core/artifactId
version6.0.0.RELEASE/version
/dependencyJava代码
public class Main {public static void main(String[] args) {RedisClient redisClient RedisClient.create(redis://127.0.0.1);MapString, String clientCache new ConcurrentHashMap();StatefulRedisConnectionString, String myself redisClient.connect();CacheFrontendString, String frontend ClientSideCaching.enable(CacheAccessor.forMap(clientCache), myself,TrackingArgs.Builder.enabled().noloop));String key csk;int count 0;while (true) {System.out.println(frontend.get(key));TimeUnit.SECONDS.sleep(3);if (count Integer.MAX_VALUE) {myself.close();redisClient.shutdown();}}}
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/89992.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!