undefined

Redis 主从复制

概念

主从复制,是指将一台Redis服务器的数据,复制到其他Redis 服务器,前者称为主节点(master/leader),后者称为从节点(slave/follower);数据的复制是单向的,只能由主节点到从节点。Master 以写为主,Slave 以读为主。

默认情况下,每台Redis 服务器都是主节点;且一个主节点可以有多个从节点(或者没有从节点),但一个从节点只能有一个主节点。

主从复制的作用主要包括:

  1. 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式
查看更多

undefined

Redis 扩缩容

redis 扩缩容一般通过垂直扩缩容的方式解决 redis 集群容量的问题,垂直扩缩容比较简单,只是 Maxmemory 的配置更改。但随着集群规模扩大,这种方式逐渐会遇到瓶颈。

  • 一方面,单个 redis 实例过大,会带来较大的运维风险和困难
  • 另一方面,宿主机容量有上限,不能无止境的扩容

查看更多

undefined

Redis 持久化

Redis 是内存数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失。所以Redis 提供了持久化功能

RDB(Redis DataBase)

在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot 快照,它恢复时是将快照文件直接读到内存里

Redis 会单独创建(Fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,在用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的。这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那么RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。我们默认的就是RDB,一般情况下不需要修改这个配置。

有时候在生产环境会将这个文件备份。

查看更多

undefined

redis 的内存淘汰策略,内存满了如何淘汰键

一、Redis 的 LRU 实现和 LFU 实现

如果按照HashMap和双向链表实现,需要额外的存储存放 next 和 prev 指针,牺牲比较大的存储空间,显然是不划算的。

redisObject 结构体(Redis 整体上是一个大的 dict,key 是一个 string,而 value 都会保存为一个 redisObject)

1
2
3
4
5
typedef struct redisObject {
...
unsigned lru:LRU_BITS; //LRU_BITS为24bit
...
} robj;

查看更多

undefined

五大数据类型

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings)散列(hashes)列表(lists)集合(sets)有序集合(sorted sets) 与范围查询, bitmapshyperloglogs地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication)LUA脚本(Lua scripting)LRU驱动事件(LRU eviction)事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)

Redis-Key

1
2
3
4
5
6
7
1. move name 1 # 移除数据库1 中的 key(name)
2. get name # 获取当前数据key的值
3. expire name 10 # 设置 key(name) 10s 过期,单位是秒
4. ttl name # 查看当前key(name)的剩余时间
5. set key value # 设置key-value
6. exists name # 判断当前的key(name)是否存在
7. type key # 查看当前key的类型

string 字符串

实现:整数值、embstr编码的简单动态字符串、简单动态字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1. set key1 v1 # 设置值
2. get key1 # 获取值
3. keys * # 获取所有的key
4. exists key1 # 判断一个key 是否存在
5. append key1 "hello" # 将key1 所对应的value增加"hello",如果当前key不存在,相当于 set key
6. strlen key1 # 查看 key1 的长度
7. incr key1 # 当前 key1 加 1
8. decr key1 # 当前 key1 减 1
9. incrby key1 5 # 设置步长,设置 key1 增量为 5
10. decrby key1 5 # 设置步长,设置 key1 减量为 5
11. getrange key1 0 3 # 截取字符串 [0, 3] 闭区间
getrange key1 0 -1 # 获取全部字符串和 get key 是一样的
12. setrange key1 1 xx # 替换指定位置的字符串,从 1 位置开始

13. setex (set with expire) # 设置过期时间
setex key1 30 "hello" # 设置 key1 的值为 “hello”,30秒后过期
14. setnx (set if not exist) # 不存在设置,在分布式锁中会常常使用
setnx key1 "hello" # 如果 key1 存在,则设置失败;如果 key1 不存在,设置成功

15. mset k1 v1 k2 v2 k3 v3 # 同时设置多个值
16. mget k1 k2 k3 # 同时获取多个值
17. msetnx k1 v1 k4 v4 # msetnx 是一个原子性的操作,要么一起成功,要么一起失败
18. getset # 先 get 后 set
getset key1 v1 如果不存在值,则返回nil, 并设置新值;如果存在值,获取原来的值,并设置新值

查看更多

undefined

1
2
3
4
5
6
7
8
对象创建的时候指定父类,qt 会在关闭窗口的时候,依次释放对象。
坐标轴左上角是(0, 0) 是二维坐标

信号可以连接信号
一个信号可以连接多个槽函数
多个信号可以连接同一个槽函数
信号和槽函数的参数 必须类型一一对应
信号的参数个数可以多于槽函数的参数个数

1. Mac OS 平台 Qt MenuBar 无法在窗体中显示菜单

Mac 默认的菜单显示在菜单栏,并且默认没有 action 的 menu 将不会显示,复用菜单将不按照预定的方式排列

解决方案:显式的设置一下

第一种方法:

查看更多

POD 类型说明

C语言当前定义的基本数据类型有 int、char、float 等整数类型、浮点类型、枚举、void、指针、数组、结构等等。然后只要碰到一串 01010110010 之类的数据,编译器都可以正确的把它解析出来。但是在C++中出现继承、派生这些概念后,编译器无法解释。为了和旧的C数据相兼容,因此C++提出了POD数据结构概念。

POD 是 Plain Old Data 的缩写,是 C++ 定义的一类数据结构概念,比如 int、float 等都是 POD 类型的。Plain 代表它是一个普通类型,Old 代表它是旧的,与几十年前的 C 语言兼容,那么就意味着可以使用 memcpy() 这种最原始的函数进行操作。两个系统进行交换数据,如果没有办法对数据进行语义检查和解释,那就只能以非常底层的数据形式进行交互,而拥有 POD 特征的类或者结构体通过二进制拷贝后依然能保持数据结构不变。也就是说,能用 C 的 memcpy() 等函数进行操作的类、结构体就是 POD 类型的数据。

基本上谈到这个概念,一般都是说某某 class、struct、union 是不是 POD 类型的。

POD特征

是不是 POD 类型的,可以用 is_pod::value 来判断。那什么样的类、结构体是拥有 POD 特性的呢?要求有两个:一个是它必须很平凡、很普通;另一个是布局有序。

1. 平凡

满足下面的2个条件即可说是平凡特征的数据类型:

查看更多

c++11 中 enable_shared_from_this 使用

c++11 之 enable_shared_from_this

enable_shared_from_this 是一个模板类

1
template< class T > class enable_shared_from_this;

std::enable_shared_from_this 能让一个对象(假设名为 t,且被一个 std::shared_ptr 对象 pt 管理)安全地生成其他额外的 std::shared_ptr 实例,他们与 pt 共享对象 t 的所有权

若一个类 T 继承 std::enable_shared_from_this<T> ,则会为该类提供成员函数:shared_from_this。当 T 类型对象 t 被一个名为 pt 的 std::shared_ptr<T> 类对象管理时,调用 T::shared_from_this 成员函数,将会返回一个新的 std::shared_ptr<T> 对象,他与 pt 共享 t 的所有权。

查看更多