一、pika
pika是360奇虎公司开源的一款类redis存储系统,主要解决的是用户使用 Redis 的内存大小超过 50G、80G 等等这样的情况,会遇到启动恢复时间长,一主多从代价大,硬件成本贵,缓冲区容易写满等问题。
Pika 就是针对这些场景的一个解决方案:
- Pika 的单线程的性能肯定不如 Redis,Pika 是多线程的结构,因此在线程数比较多的情况下,某些数据结构的性能可以优于 Redis;
- Pika 肯定不是完全优于 Redis 的方案,只是在某些场景下面更适合,DBA 可以根据业务的场景挑选合适的方案。
二、redis 单机存在的问题
挂断数据丢失,容量小,内存有上限
三、redis集群方案
- 1.codis, go语言编写,有中心点,通过网关转发。codis底层会处理请求的转发,不停机的数据迁移等工作,所有后边的事情,对于前面的客户端来说是透明的,可以简单的认为后边连接的是一个内存无限大的redis服务。
- 2.redis-cluster ,采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他节点连接。
- 3.twemproxy代理中间件,利用中间件做分片的技术。twemproxy处于客户端和服务器的中间,将客户端发来的请求,进行一定的处理后(sharding),再转发给后端真正的redis服务器。
- 4.哨兵模式,Sentinel(哨兵)是Redis的高可用性解决方案:由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器以及这些主服务器下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。
四、redis 单进程单线程还能达到10w吞吐量原因
- 纯内存
- 单线程
- 无锁
五、redis 数据形式
- sds:string
- list
- set
- zset
- hash
- list
- ziplist
- quicklist
- strearm :5之后才有
- GEO:地理位置相关
- HyperLogLog:日志
- skiplist::为了实现sorted set
六、redis 命令
七、SDS结构
#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
// 内部使用
struct __attribute__ ((__packed__)) sdshdr5 {
unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
char buf[];
};
// 最大允许2^8-2(\0)
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 低3位标识类型,高位标识大小 */
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 低3位标识类型,高5位未用 */
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 低3位标识类型,高5位未用*/
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 低3位标识类型,高5位未用*/
char buf[];
};
八、结构体的柔性数组
#include<stdio.h>
int main() {
struct sdshdr64 {
long long len; /* used */
long long alloc; /* excluding the header and null terminator */
unsigned char flags; /* 3 lsb of type, 5 unused bits */
char buf[];
};
struct sdshdr64 s;
s.len = 1;
s.alloc = 2;
printf("长度是%d", sizeof(s));
return 1;
}
结论:柔性数组影响对齐,但是不计入大小。
九、gdb调试redis
后台启动redis-service,ps aux|grep redis 查看端口号,gdb 端口号,在setCommand打断点
进入两个关键函数setGenericCommand和setKey
执行 set liuyj aa
十、笔记地址