https://www.w3cschool.cn/redis/redis-pub-sub.html
redis-server --maxclients 100000
客户端命令
CLIENT LIST 返回连接到 redis 服务的客户端列表
CLIENT SETNAME 设置当前连接的名称
CLIENT GETNAME 获取通过 CLIENT SETNAME 命令设置的服务名称
CLIENT PAUSE 挂起客户端连接,指定挂起的时间以毫秒计
CLIENT KILL 关闭客户端连接
LRANGE list 0 10 这个命令会返回11个元素
LRANGE list 0 -1 表示从第1个到最后一个。-1是列表的最后一个元素,-2 是倒数第二个
存多个字段:HMSET user_1 userId 123 userName clf email chenlongfei@163.com。
1. Redis自带的PUB/SUB机制,即发布-订阅模式。这种模式生产者(producer)和消费者(consumer)是1-M的关系,即一条消息会被多个消费者消费,当只有一个消费者时即可以看做一个1-1的消息队列,但这种方式并不适合题主的场景。首先,数据可靠性的无法保障,题主的数据最终需要落库,如果消息丢失、Redis宕机部分数据没有持久化甚至突然的网络抖动都可能带来数据的丢失,应该是无法忍受的。其次,扩展不灵活,没法通过多加consumer来加快消费的进度,如果前端写入数据太多,同步会比较慢,数据不同步的状态越久,风险越大,当然可以通过channel拆分的方式来解决,虽然不灵活,但可以规避。这种方案更适合于对数据可靠性要求不高,比如一些统计日志打点。
2. Redis的PUSH/POP机制,利用的Redis的列表(lists)数据结构。比较好的使用模式是,生产者lpush消息,消费者brpop消息,并设定超时时间,可以减少redis的压力。这种方案相对于第一种方案是数据可靠性提高了,只有在Redis宕机且数据没有持久化的情况下丢失数据,可以根据业务通过AOF和缩短持久化间隔来保证很高的可靠性,而且也可以通过多个client来提高消费速度。但相对于专业的消息队列来说,该方案消息的状态过于简单(没有状态),且没有ack机制,消息取出后消费失败依赖于client记录日志或者重新push到队列里面。
最后再来看题主的需求,是希望先写Redis,再异步同步到mysql里面,期望数据的最终一致性。这样带来的好处是前端写的请求飞速啊(不用落盘当然快),问题是很复杂,而且不太合理。假设是合理的话,就应该选择一个更可靠的消息中间件,比如Redis作者开源的Disque,或者阿里开源RocketMQ,以及基于Golang的nsq等,Redis更适合用来存数据。
最大连接数
在 Redis2.4 中,最大连接数是被直接硬编码在代码里面的,而在2.6版本中这个值变成可配置的。maxclients 的默认值是 10000,你也可以在 redis.conf 中对这个值进行修改。
config get maxclients
1) "maxclients"
2) "10000"
redis参考文档:http://redisdoc.com
LPOP key value,移除key的头元素。
LPUSH key value [value ...]将一个或多个值 value 插入到列表 key 的表头。如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表头: 比如说,对空列表 mylist 执行命令 LPUSH mylist a b c ,列表的值将是 c b a ,这等同于原子性地执行 LPUSH mylist a 、 LPUSH mylist b 和 LPUSH mylist c 三个命令。如果 key 不存在,一个空列表会被创建并执行 LPUSH 操作。
主要做数据缓存,减少mysql数据库的压力。
从效率来说:Redis的数据存放在内存,所以速度快但是会受到内存空间限制。MySQL存放在硬盘,在速度上肯定没有Redis快,但是存放的数据量要多的多。从功能来说:Redis是一个K-V数据库,同时还支持List/Hash/Set/Sorted Set等几个简单数据结构,所以只能以这些数据结构为基础实现功能。而MySQL这点就不必说了。最后需要提到的是,我一开始使用Redis时也觉得它的功能非常强大,以致于各种需求都下意识的去寻找Redis的解决方案(详见:Redis应用场景)。不过也有几个需要注意的点:1. Redis虽然默认提供了RDB和AOF两种数据持久化方式,不过很多前辈还是建议我不要太信任Redis的持久化功能,所以重要数据最好还是存放在MySQL,然后在Redis中做缓存。2. 项目初期在访问量低的时候通过Redis实现了很多功能,当用户量大了以后很快发现内存不够用了就会很尴尬。合理的利用有限的内存,将读(写)频繁的热数据放在Redis中才能更好感受到它带来的性能提升。
从效率来说:Redis的数据存放在内存,所以速度快但是会受到内存空间限制。MySQL存放在硬盘,在速度上肯定没有Redis快,但是存放的数据量要多的多。从功能来说:Redis是一个K-V数据库,同时还支持List/Hash/Set/Sorted Set等几个简单数据结构,所以只能以这些数据结构为基础实现功能。而MySQL这点就不必说了。最后需要提到的是,我一开始使用Redis时也觉得它的功能非常强大,以致于各种需求都下意识的去寻找Redis的解决方案(详见:Redis应用场景)。不过也有几个需要注意的点:1. Redis虽然默认提供了RDB和AOF两种数据持久化方式,不过很多前辈还是建议我不要太信任Redis的持久化功能,所以重要数据最好还是存放在MySQL,然后在Redis中做缓存。2. 项目初期在访问量低的时候通过Redis实现了很多功能,当用户量大了以后很快发现内存不够用了就会很尴尬。合理的利用有限的内存,将读(写)频繁的热数据放在Redis中才能更好感受到它带来的性能提升。
golang 的并发高,你可以理解为你有一个 server,同时 10w 个长连接。golang 可以给每个连接一个 goroutine。你用 python/c/java 都做不到,需要些比较复杂的线程池或者用 epoll 之类的。
golang 又不止是让你用来写 CRUD 的,你若有机会做个高性能的网络产品比如 API 网关,golang 自然要比 python 性能好的多。
实际 golang 并不是并发高,而是只需要按照多线程阻塞模式写网络程序,编译器自动转换成为 协程+epoll。
没实测,理论上 golang 的性能和 c 语言用 epoll 写的性能是一致的,可能由于自动垃圾回收性能还次于c。
但是重点是写起来简单啊,epoll 之类的用起来比较麻烦,但是 golang 只需要疯狂开协程就行,一个连接来了,直接开一个协程 阻塞 read,阻塞 write,高兴了一个连接开两个协程,一个负责 read 一个负责 write 也没问题。开几十万协程也没什么性能问题。
瓶颈在io,不在golang。
就算是用 php,python 这种脚本语言开发网站,实际性能瓶颈也在 mysql,更别说 golang 了。
先别急着分库分表,缓存做好了么?
先做缓存,我们一秒 2k 个动态请求,mysql 单机搞定,而且流量很低
别急着分库分表, 索引做好了么,引擎调优了么, 数据项精简了么?
估计跑出来的结果都差不多,mysql 才是瓶颈,不要 db 才能对比两者的并发
,因此Redis可以用来实现很多有用的功能,比方说用他的List来做FIFO双向链表,实现一个轻量级的高性 能消息队列服务,用他的Set可以做高性能的tag系统等等。另外Redis也可以对存入的Key-Value设置expire时间,因此也可以被当作一 个功能加强版的memcached来用。
redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销
Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。Redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争,但是在Jedis客户端对Redis进行并发访问时会发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是