> For the complete documentation index, see [llms.txt](https://maxwell.gitbook.io/way-to-architect/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://maxwell.gitbook.io/way-to-architect/shu-ju-ku/redis.md).

# Redis

## redis和memcached的区别

Redis相比Memcached来说，拥有更多的数据结构和并支持更丰富的数据操作，通常在Memcached里，你需要将数据拿到客户端来进行类似的修改再set回去。这大大增加了网络IO的次数和数据体积。在Redis中，这些复杂的操作通常和一般的GET/SET一样高效。所以，如果需要缓存能够支持更复杂的结构和操作，那么Redis会是不错的选择。

1. 内存使用效率对比：使用简单的key-value存储的话，Memcached的内存利用率更高，而如果Redis采用hash结构来做key-value存储，由于其组合式的压缩，其内存利用率会高于Memcached。
2. 性能对比：由于Redis只使用单核，而Memcached可以使用多核，所以平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中，Memcached性能要高于Redis，虽然Redis最近也在存储大数据的性能上进行优化，但是比起Memcached，还是稍有逊色。

可以这么回答：

* Redis支持的数据类型更丰富（因而能够支持更复杂的结构和操作，减少网络IO的次数和数据体积）
* Memcached本身并不支持分布式，因此只能在客户端通过像一致性哈希这样的分布式算法来实现Memcached的分布式存储。
* Redis支持内存数据的持久化的（两种方式：RDB快照和AOF日志），而memcached是不支持数据持久化操作的。
* 内存管理机制不同

## redis支持哪些数据结构

redis支持五种数据结构：

* Strings：字符串
* Lists：列表，是一个双向链表结构
* Hashes：哈希
* Sets：集合，与Lists的区别是，Lists中可以存储多个相同的字符串，而Sets中存储的每个字符串都不相同
* Sorted Sets：有序集合，使用与Hashes一样的键值对存储，只是它的值为score(分值，即排序依据)

## redis是单线程的吗，所有的工作都是单线程吗

说redis单线程指的是网络请求模块使用了一个线程（所以不需考虑并发安全性），其他模块仍用了多个线程，比如复制、持久化等。

## redis如何存储一个String的

Redis中使用的字符串是通过包装的、基于c语言字符数组实现的一个抽象数据结构；

Redis对key的长度是有限制的，最大长度是512MB；

二进制安全字符串；

//todo：我也不知道我在说什么

## redis的部署方式，主从，集群，redis的哨兵模式

官方提供redis-cluster集群方式

todo

## 一个key值如何在redis集群中找到存储在哪里

当客户端向集群中某节点发送与数据库键有关的命令时，接收命令的节点会计算出要处理的key属于哪个槽，并检查这个槽是否指派给了自己：

* 如果key所在的槽正好就指派给了当前节点，那么节点直接执行这个命令
* 如果key所在的槽并没有指派给当前节点，那么节点会向客户端返回一个MOVED错误（其中包含key所在的槽所在的节点），指引客户端redirect到正确的节点，并再次发送之前想要执行的命令。

## redis持久化策略

[Redis](http://redis.io/)有两种持久化的方式：快照（`RDB`文件）和追加式文件（`AOF`文件）：

* Redis的持久化是可以禁用的，就是说你可以让数据的生命周期只存在于服务器的运行时间里。
* 两种方式的持久化是可以同时存在的，但是当Redis重启时，AOF文件会被优先用于重建数据。

RDB

RDB是指将某个时间点上数据库状态保存到一个RDB文件中，RDB文件是一个经过压缩的二进制文件，通过该文件可以还原成RDB文件的数据库状态。

RDB持久化可以手动执行，也可以根据服务器配置选项定期执行。

AOF

AOF是通过保存Redis服务器所执行的写命令来记录数据库状态的。它有3个选项来设置appendfsync:

* always：在每次事件循环中，都将aod\_buf中的所有内容写入到AOF文件中，并同步AOP文件；效率最慢，但最安全，即使宕机，也只是丢失一个事件循环中所产生的命令数据。
* everysec：在每次事件循环中，都将aod\_buf中的所有内容写入到AOF文件中，但每隔一秒再去同步AOF文件；效率足够快，宕机时只丢失一秒钟的数据。
* no：在每次事件循环中，都将aod\_buf中的所有内容写入到AOF文件中，但何时同步AOF文件由操作系统控制；效率最高，但最不安全。

> 上面，写入和同步是操作系统范畴中的概念：为了提高文件的写入效率，当用户将数据写入到文件中的时候，操作系统会将写入数据暂存在一个内存缓冲区中（这一步叫写入），等到缓冲区填满或超过指定时限后，才真正将缓冲区中的数据写到磁盘中（这一步叫同步）。

AOF还提供重写功能：创建一个新的AOF文件来替代旧的AOF文件，新旧文件中表示的数据库状态相同，但新文件中会对旧文件中的命令进行重写，以节省空间，解决AOF文件体积膨胀的问题。

RDB与AOF的直观概念比较，比如执行

```
set msg "hello"
```

RDB是将msg这个键的键值保存到RDB文件中；

AOF是将服务器执行的set命令保存到AOF文件中；

内容来源：

[Redis 和 Memcached 的区别](http://blog.jobbole.com/103106/)

《Redis设计与实现》
