三级缓存(redis,nginx,zookper,堆)

1安装虚拟机

1.1创建 在local 下面创建 nginx redis mysql jdk tomcat

上传redis

创建

mkdir -p /etc/redis-cluster

mkdir -p /var/log/redis

mkdir -p /var/redis/7001>>7006

 

安装yum install gcc-c++

wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz

tar -xzvf tcl8.6.1-src.tar.gz

cd  /usr/local/tcl8.6.1/unix/

./configure  

make && make install

 

安装之后安装redis

 

使用redis-3.2.8.tar.gz(截止2017年4月的最新稳定版)

tar -zxvf redis-3.2.8.tar.gz

cd redis-3.2.8

make && make test && make install

 

 

(1)redis utils目录下,有个redis_init_script脚本

(2)将redis_init_script脚本拷贝到linux的/etc/init.d目录中,将redis_init_script重命名为redis_7001,7001是我们希望这个redis实例监听的端口号

(3)修改redis_7001脚本的第6行的REDISPORT,设置为相同的端口号(默认就是6379)

(4)创建两个目录:/etc/redis(存放redis的配置文件),/var/redis/6379(存放redis的持久化文件)

(5)修改redis配置文件(默认在根目录下,redis.conf),拷贝到/etc/redis目录中,修改名称为7001.conf

//修改的参数

port 7001

cluster-enabled yes

cluster-config-file /etc/redis-cluster/node-7001.conf

cluster-node-timeout 15000

daemonize yes

pidfile /var/run/redis_7001.pid

dir /var/redis/7001

logfile /var/log/redis/7001.log

bind 192.168.31.187

appendonly yes

1.1.1数据清除机制配置

redis.conf

 

maxmemory,设置redis用来存放数据的最大的内存大小,一旦超出这个内存大小之后,就会立即使用LRU算法清理掉部分数据

 

如果用LRU,那么就是将最近最少使用的数据从缓存中清除出去

 

对于64 bit的机器,如果maxmemory设置为0,那么就默认不限制内存的使用,直到耗尽机器中所有的内存为止; 但是对于32 bit的机器,有一个隐式的闲置就是3GB

 

maxmemory-policy,可以设置内存达到最大闲置后,采取什么策略来处理

 

(1)noeviction: 如果内存使用达到了maxmemory,client还要继续写入数据,那么就直接报错给客户端

(2)allkeys-lru: 就是我们常说的LRU算法,移除掉最近最少使用的那些keys对应的数据

(3)volatile-lru: 也是采取LRU算法,但是仅仅针对那些设置了指定存活时间(TTL)的key才会清理掉

(4)allkeys-random: 随机选择一些key来删除掉

(5)volatile-random: 随机选择一些设置了TTL的key来删除掉

(6)volatile-ttl: 移除掉部分keys,选择那些TTL时间比较短的keys

 

在redis里面,写入key-value对的时候,是可以设置TTL,存活时间,比如你设置了60s。那么一个key-value对,在60s之后就会自动被删除

 

redis的使用,各种数据结构,list,set,等等

 

allkeys-lru

1.2安装rubby

yum install -y ruby

yum install -y rubygems

gem install redis

把对应的gem文件安装好.

gem install redis-3.0.0.gem

把创建脚本复制过去

cp /usr/local/redis/redis-3.2.8/src/redis-trib.rb /usr/local/bin

启动全部的redis 在ini.d下面启动

开始创建集群redis-trib.rb create --replicas 1 192.168.25.10:7001 192.168.25.10:7002 192.168.25.10:7003 192.168.25.10:7004 192.168.25.10:7005 192.168.25.10:7006

 

检查是否成功

redis-trib.rb check 192.168.25.10:7001

看到这个表示成功了

 

连接redis 集群的方案

 ./redis-cli -h 192.168.25.10 -p 7001

 

2安装jdk

把东西弄到    解压后的jdk目录  /usr/local/jdk/jdk1.8.0_171

2.1修改配置文件

vim /etc/profile


添加如下内容:JAVA_HOME根据实际目录来
JAVA_HOME=/usr/local/jdk/jdk1.8.0_171

CLASSPATH=$JAVA_HOME/lib/
PATH=$PATH:$JAVA_HOME/bin
export PATH JAVA_HOME CLASSPATH

2.2重新关联配置文件

source /etc/profile

 

3安装tomcat 并关闭防火墙(省略)

4加去新的mask和solve

4.1添加mask

创建 mkdir -p /var/redis/7007和 mkdir -p /var/redis/7008

 

把权限int.d下面的启动脚本复制一份 改名+改端口

 

把配置文件修改放在/etc/redis

 

查看日志 cat /var/log/redis/7007.log

 

redis-trib.rb add-node 192.168.25.10:7007 192.168.25.10:7001

 

迁移solte

 

redis-trib.rb reshard 192.168.25.10:7001

 

(100  all  yes)

4.2添加slave

 

redis-trib.rb add-node --slave --master-id 359f902499cc302cce5865539b7d0168353c4aea 192.168.25.10:7008 192.168.25.10:7001

 

 

4、删除node

 

先用resharding将数据都移除到其他节点,确保node为空之后,才能执行remove操作

 

redis-trib.rb del-node 192.168.25.10:7001 bd5a40a6ddccbd46a0f4a2208eb25d2453c2a8db

 

2个是1365,1个是1366

 

当你清空了一个master的hashslot时,redis cluster就会自动将其slave挂载到其他master上去

 

这个时候就只要删除掉master就可了(注意:必须全部删除节点。不然要出错)

 

 

5安装mysql

5.1把rpm的文件上传到mysql里面去

yum localinstall mysql-community-release-el6-5.noarch.rpm

yum install mysql-server

service mysqld start

5.2设置密码

/usr/bin/mysqladmin -u root password 'root'

5.3申请远程登陆的账号密码登陆

mysql  -u root -p

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;

5.4不区分大小写

 

/etc/my.cnf,在[mysqld]后面加上lower_case_table_names=1,重启mysql服务即可。

5.5重启mysql

Service mysqld restart

 

6整合sprint boot 和mybaties

6.1 Pom文件

6.1.1代码:文件里面有

7代码实现的理论

 

第一块,是做实时性比较高的那块数据,比如说库存,销量之类的这种数据,我们采取的实时的缓存+数据库双写的技术方案,双写一致性保障的方案

int h;

return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);

 

(queueNum - 1) & hash

 

7.1、线程池+内存队列初始化

2、Java 线程池
Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

 

注册服务Listenener

@Bean

public ServletListenerRegistrationBean servletListenerRegistrationBean(){

    ServletListenerRegistrationBean servletListenerRegistrationBean = new ServletListenerRegistrationBean();

    servletListenerRegistrationBean.setListener(new InitListener());

    return servletListenerRegistrationBean;

}

 

java web应用,做系统的初始化,一般在哪里做呢?

 

ServletContextListener里面做,listener,会跟着整个web应用的启动,就初始化,类似于线程池初始化的构建

 

spring boot应用,Application,搞一个listener的注册

 

核心代码

初始化一个线程池

Private ExecutorService threedpool =Exectuors.newFixdeThreadPool(10);

Threadpool.submit的必须是

Runnabl()与Callable()的接口类.

如果是一个多线程协作程序,比如菲波拉切数列,1,1,2,3,5,8…使用多线程来计算。 
但后者需要前者的结果,就需要用callable接口了。 
callable用法和runnable一样,只不过调用的是call方法,该方法有一个泛型返回值类型,你可以任意指定。所以这里选择的callAble

代码使用单利

public class RequestProcessorThread implements Callable {

 

}

上面的代码方式:

使用一个数组 和一个Request的接口.来绑定线程

 

7.2、两种请求对象封装

 

7.3、请求异步执行Service封装

BlockingQueue的核心方法:

1.放入数据

    (1)offer(anObject):表示如果可能的话,将anObject加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则返回false.(本方法不阻塞当前执行方法

 的线程);       
       (2)offer(E o, long timeout, TimeUnit unit):可以设定等待的时间,如果在指定的时间内,还不能往队列中加入BlockingQueue,则返回失败。

    (3)put(anObject):把anObject加到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的线程被阻断直到BlockingQueue里面有空间再继续.

2. 获取数据

    (1)poll(time):取走BlockingQueue里排在首位的对象,若不能立即取出,则可以等time参数规定的时间,取不到时返回null;

    (2)poll(long timeout, TimeUnit unit):从BlockingQueue取出一个队首的对象,如果在指定时间内,队列一旦有数据可取,则立即返回队列中的数据。否则知道时间

超时还没有数据可取,返回失败。

    (3)take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的数据被加入; 

    (4)drainTo():一次性从BlockingQueue获取所有可用的数据对象(还可以指定获取数据的个数),通过该方法,可以提升获取数据效率;不需要多次分

 

7.4、两种请求Controller接口封装

 

7.5、读请求去重优化

 

7.6、空数据读请求过滤优化

===========日志===========: 接收到更新商品库存的请求,商品id=1, 商品库存数量=10

===========日志===========: 路由内存队列,商品id=1, 队列索引=1

===========日志===========: 工作线程处理请求,商品id=1

===========日志===========: 数据库更新请求开始执行,商品id=1, 商品库存数量=10

===========日志===========: 已删除redis中的缓存,key=product:inventory:1

===========日志===========: 接收到一个商品库存的读请求,商品id=1

===========日志===========: 路由内存队列,商品id=1, 队列索引=1

===========日志===========: 已修改数据库中的库存,商品id=1, 商品库存数量=10

===========日志===========: 工作线程处理请求,商品id=1

===========日志===========: 已查询到商品最新的库存数量,商品id=1, 商品库存数量=10

===========日志===========: 已更新商品库存的缓存,商品id=1, 商品库存数量=10, key=product:inventory:1

===========日志===========: 在200ms内读取到了redis中的库存缓存,商品id=1, 商品库存数量=10

===========日志===========: 接收到更新商品库存的请求,商品id=1, 商品库存数量=100

===========日志===========: 路由内存队列,商品id=1, 队列索引=1

===========日志===========: 工作线程处理请求,商品id=1

===========日志===========: 数据库更新请求开始执行,商品id=1, 商品库存数量=100

===========日志===========: 已删除redis中的缓存,key=product:inventory:1

===========日志===========: 接收到一个商品库存的读请求,商品id=2

===========日志===========: 路由内存队列,商品id=2, 队列索引=0

===========日志===========: 工作线程处理请求,商品id=2

===========日志===========: 已查询到商品最新的库存数量,商品id=2, 商品库存数量=100

===========日志===========: 已更新商品库存的缓存,商品id=2, 商品库存数量=100, key=product:inventory:2

===========日志===========: 在200ms内读取到了redis中的库存缓存,商品id=2, 商品库存数量=100

===========日志===========: 接收到一个商品库存的读请求,商品id=1

===========日志===========: 路由内存队列,商品id=1, 队列索引=1

===========日志===========: 已修改数据库中的库存,商品id=1, 商品库存数量=100

===========日志===========: 工作线程处理请求,商品id=1

===========日志===========: 已查询到商品最新的库存数量,商品id=1, 商品库存数量=100

===========日志===========: 已更新商品库存的缓存,商品id=1, 商品库存数量=100, key=product:inventory:1

===========日志===========: 在200ms内读取到了redis中的库存缓存,商品id=1, 商品库存数量=100

8代码实现要求不高的数据

第二块,是做实时性要求不高的数据,比如说商品的基本信息,等等,我们采取的是三级缓存架构的技术方案,就是说由一个专门的数据生产的服务,去获取整个商品详情页需要的各种数据,经过处理后,将数据放入各级缓存中,每一级缓存都有自己的作用

9.安装zookeeper

1、zookeeper集群搭建

 

将课程提供的zookeeper-3.4.5.tar.gz使用WinSCP拷贝到/usr/local目录下。

对zookeeper-3.4.5.tar.gz进行解压缩:tar -zxvf zookeeper-3.4.5.tar.gz。

对zookeeper目录进行重命名:mv zookeeper-3.4.5 zk

2配置zookeeper相关的环境变量

2.1修改配置文件

Vi  /etc/profile

export ZOOKEEPER_HOME=/usr/local/zk

export PATH=$ZOOKEEPER_HOME/bin:$

source  /etc/profile

 

3修改配置文件

cd zk/conf

cp zoo_sample.cfg zoo.cfg

 

server.1=192.168.25.10:2881:3881

server.2=192.168.25.10:2882:3882

server.3=192.168.25.10:2883:3883

vi zoo.cfg

修改:dataDir=/usr/local/zookeeper1/data

...

 

./zookeeper3/bin/zkServer.sh start

...

sudo netstat -nltp | grep 2185

sudo kill -9 3071

 

开启.然后看状态

./zookeeper3/bin/zkServer.sh start

看到这个便是zookeeper安装成功了

 

10、kafka集群搭建

 

scala,我就不想多说了,就是一门编程语言,现在比较火,很多比如大数据领域里面的spark(计算引擎)就是用scala编写的

 

将课程提供的scala-2.11.4.tgz使用WinSCP拷贝到/usr/local目录下。

对scala-2.11.4.tgz进行解压缩:tar -zxvf scala-2.11.4.tgz。

对scala目录进行重命名:mv scala-2.11.4 scala

10.1修改Scala的环境变量

vi ~/.bashrc

export SCALA_HOME=/usr/local/scala

export PATH=$SCALA_HOME/bin

source ~/.bashrc

 

Scala -version

 

安装kafka

将课程提供的kafka_2.9.2-0.8.1.tgz使用WinSCP拷贝到/usr/local目录下。

对kafka_2.9.2-0.8.1.tgz进行解压缩:tar -zxvf kafka_2.9.2-0.8.1.tgz。

对kafka目录进行改名:mv kafka_2.9.2-0.8.1 kafka

 

配置kafka

vi /usr/local/kafka/config/server.properties

broker.id:依次增长的整数,1、2、3,集群中Broker的唯一id

zookeeper.connect=192.168.25.10:2181,192.168.25.10:2182,192.168.25.10:2183

 

 

 

你可能感兴趣的:(三级缓存(redis,nginx,zookper,堆))