一、分布式解决 Session 的问题
在单站点中,可以将在线用户信息存储在Session中,随时变更获取信息;在多站点分布式集群如何做到Session共享呢?架设一个Session服务,供多服务使用。
频繁使用的数据存在DB端,频繁的DB连接,频繁的IO;数据存于内存中更能减少性能的消耗,更能提高使用效率。
集群化分布式时,为解决以上现象,建立缓存服务显得尤为重要。
建立缓存服务选择性很多,如:Redis、MongoDB等,以下以 Redis 为例:
二、内存数据库 Redis
Remote Dictionary Server;
远程字典服务,Key/Value 存储系统、列存储、文档型存储等,NoSQL开源内存数据库。最多的使用场景是作为数据缓存,存在于应用与DB之间,减少对DB的访问,提高数据操作的性能。
下图展示了缓存服务在整体架构中的位置:
2.1 Redis 特性
高性能 / 高可用 / 持久化 / 集群化,单实例每秒读写达10万次;
丰富的数据类型 :String / Hash / Set / Zset / 队列 / 订阅 / 发布;
高性能数据结构:SDS / Intset / ziplist / listpack / quicklist / skiplist;
支持 ACL:Access Control List;精细化的权限管理策略;
单线程处理事务:顺序执行,容易上锁;
多线程处理辅助功能:连接请求 / 持久化等;
单线程处理事务的优缺点
优点:顺序执行,不存在脏读脏写幻读等情况,不存在死锁,不存在线程管理的开销。
缺点:单线程的性能瓶颈,多处理器的资源浪费。
2.2 单线程IO多路复用
通常情况下,同时连接 Redis 的客户端有成千上万的,但 Redis 只有一个主线程处理事务,那如何做到多路连接集中到一个线程处理呢?
当多个客户端同时发起连接后,这也是需要一个过程的,也是有连接完成的先后,谁连接完成就会告诉 Redis,这里的告诉用的是回调方式,Redis就会把他的任务放到单一的队列中,队列的另一头连接着主线程。
在这个过程当中,多路的连接汇集到一个有足够处理能力的队列中进行传输;是不是可以理解为:多路连接重复利用了单个管道;我想...这里也是体现了 Redis 的多路复用技术。当然,单单就多路复用来讲,也会是多路集中到一路,然后这一路又分成了多路到各各目标。
多路复用也有不同的算法:select、poll、epoll,Redis用的是epoll算法,所以其中有回调的动作,目前而言,epoll是最高效的;关于每个具体的算法,有兴趣的同学可以继续研究一下。
2.3 启动 Redis
用 Docker 启动 Redis 简单示例:
1、拉取镜像docker pull redis
2、运行容器 docker run -d --name=some-redis redis
3、连接到 Redis docker exec -it some-redis redis-cli
Redis Docker版默认是没有配置文件的,官网说:可以再生成镜像方式解决...
既然没有配置文件,那 Redis 启动完全是按所有配置项的默认值运行的;如下传参启动:
# 启动 redis-server,多参数配置
docker run -d --name some-redis -p 6379:6379 redis redis-server \
--bind 0.0.0.0 \ # 支持任意的连接
--save 60 1 \ # 每60秒 持久化一次
--protected-mode no \ # 取消保护模式
--requirepass 123456 # 登录密码 123456;连接后用 auth {passwd} 方式登录
传参也就是覆盖了配置项的默认值,以下查看覆盖后的配置项效果:config get *
列出所有配置项
Redis 启动后,都包含 redis-server / redis-client;
所以任意 Redis 都可用 redis-client 连接到其它 redis-server:docker exec -it some-redis redis-cli -h {目标IP} -p {目标端口}
2.4 重要配置项
通常配置参数于配置文件中;比如:/etc/redis/redis.conf
配置项 | 说明 |
---|---|
bind | 可访问限制,白名单;注释后不限制 |
port | 对外端口 |
timeout | 连接后,没有通信任务的空闲时间,超出此时长后自动断开 |
daemonize | 后台运行(容器运行时忽略) |
protected-mode | 只能本地访问的保护模式 |
tcp-backlog | 网络连接队列最大连接数(对应Linux内核参数 net.core.somaxconn,有关命令sysctl ) |
tcp-keepalive | 网路通信检测间隔,网络是否已断开(当timeout为0才起效吧) |
pidfile | 存放ProcessID编号的文件Pid的存放目录(后台运行时才会产生pid文件,容器时是否忽略) |
loglevel | 日志级别 |
logfile | 日志文件目录 |
database | 数据库个数 |
requirepass | Client 连接密码 |
maxclients | 客户端同时最大连接数(对应Linux user openfile limit,必设& |