上传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
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
yum install -y ruby
yum install -y rubygems
gem install redis
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
把东西弄到 解压后的jdk目录 /usr/local/jdk/jdk1.8.0_171
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
source /etc/profile
创建 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)
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就可了(注意:必须全部删除节点。不然要出错)
yum localinstall mysql-community-release-el6-5.noarch.rpm
yum install mysql-server
service mysqld start
/usr/bin/mysqladmin -u root password 'root'
mysql -u root -p
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
/etc/my.cnf,在[mysqld]后面加上lower_case_table_names=1,重启mysql服务即可。
Service mysqld restart
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
(queueNum - 1) & hash
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的接口.来绑定线程
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获取所有可用的数据对象(还可以指定获取数据的个数),通过该方法,可以提升获取数据效率;不需要多次分
===========日志===========: 接收到更新商品库存的请求,商品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
将课程提供的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.1修改配置文件
Vi /etc/profile
export ZOOKEEPER_HOME=/usr/local/zk
export PATH=$ZOOKEEPER_HOME/bin:$
source /etc/profile
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安装成功了
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
vi ~/.bashrc
export SCALA_HOME=/usr/local/scala
export PATH=$SCALA_HOME/bin
source ~/.bashrc
Scala -version
将课程提供的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