Thursday, December 31, 2020

Redis命令大全,满足你的日常工作,看这一篇就够了(求点赞)

前言(求点赞)

jvm我们讲了两篇文章,为了不让大家学习疲劳,我们几个技术穿插着来讲,我们今天讲讲Redis的各种命令,这篇会把大家日常需要用到的命令全都列出来,满足你们的日常工作需求

redis五大数据类型


redis键(key)

常用命令

命令注释
keys *获取所有的key
select 0(库角标)选择第几个库
move key 0(库角标)将当前的数据库key移动到某个数据库,目标库有,则不能移动
flush 0(库角标)清除指定库
randomkey获取随机key
type keykey的类型
set key value设置key和value
get key获取key的value
mset key1 value1 key2 value2批量设置key、value
mget key1 key2 key3批量获取value
del key删除key
exists key判断是否存在key
expire key second(秒)给key设置过期时间
pexpire key millisecond (毫秒)给key设置过期时间
persist key删除过期时间,持久保存key

String类型

简介

String是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。

String类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。

String类型是Redis最基本的数据类型,一个redis中字符串value最多可以是512M

存储结构类似:key:value

常用命令

命令注释
set key value设置值
get key获取值
getrange key start end获取指定范围的value
getset key value设置新value,并返回旧value
getbit key offset获取字符串中某个位置的字符
mget key1 key2获取多个value
setex key second(秒) value设置key、value,同时设置过期时间
setnx key valuekey不存在时设置key
setrange key offset value用新value替换老value部分字符,从offset开始替换
strlen key获取value长度
mset key1 value1 key2 value2批量设置key、value
msetnx key1 value1 key2 value2批量设置,当且仅当所有要设置的key都不存在时
psetex key milliseconds(毫秒) value设置过期时间,单位毫秒
incr key如果value是数字,使用这个语法使数字自增1
incrby key increment给value增加指定的值increment
decr key给value减去1
decrby key decrement给value减去指定的值decrement
append key value将value追加到key原来的value尾部

List类型

简介

它是一个字符串链表,left、right都可以插入添加;

如果键不存在,创建新的链表; 如果键已存在,新增内容; 如果值全移除,对应的键也就消失了。

链表的操作无论是头和尾效率都极高,但假如是对中间元素进行操作,效率就很惨淡了。

key是列表的名称,value是列表。

存储结构类似:key:[value1, value2, value3, value4]

常用命令

命令注释
blpop key timeout在timeout时间内,获取并移除列表的第一个元素
brpop key1 timeout在timeout时间内,获取并移除列表的最后一个元素
brpoplpush source destination timeout在timeout时间内,从source列表中取出一个值,放到destination列表中
lindex key index获取列表index位置的值
linsert key BEFOREAFTER value1 value2
llen key返回列表的长度
lpop key获取并移除列表的第一个元素
lpush key value value2将一个或多个value插入到列表的头部
lpushx key value当key已经存在的时候,向列表的头部插入value
lrange key start end获取列表部分数据,从start到end范围
lrem key count valuecount>0,从列表的头部开始算起,移除count个value相同的数据;count<0,从列表的尾部开始算起,移除count绝对值个value相同的数据;count=0,全部移除value相同的数据
lset key index value在列表index位置设置value
ltrim key start end保留start到end内的数据,其余的全部删除
rpop key获取并移除列表最后一个元素
rpoplpush source destination移除source列表最后一个元素,并把该元素添加到destination列表的头部
RPUSH key value1 value2将一个或多个value添加到列表的尾部
rpushx key value为已经存在的列表添加值

Hash类型

简介

hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。

存储结构类似:key:{field1:value1, field2:value2, field3:value3}

如:HMSET keyName name "redis tutorial" description "redis basic commands for caching"

常用命令

命令注释
hdel key field1 field2删除key中一个或多个field及value
hexists key field查看哈希表key中,指定的field字段是否存在
hget key field在key中查找filed字段的value值
hgetall key获取在哈希表中指定 key 的所有字段和值
hincrby key field increment为哈希表 key 中的指定字段的整数值加上增量increment
hincrbyfloat key field increment为哈希表 key 中的指定字段的浮点数值加上增量 increment 。
hkeys key获取所有哈希表中的字段
hlen key获取哈希表中字段的数量
hmget key field1 field2获取所有指定字段的值
hmset key field1 value1 field2 value2同时将多个 field-value对设置到哈希表 key 中
hset key field value将哈希表 key 中的字段 field 的值设为 value 。
hsetnx key field value只有在字段 field 不存在时,设置哈希表字段的值。
hvals key获取哈希表中所有值。
hscan key cursor [MATCH pattern] [COUNT count]迭代哈希表中的键值对。

set类型

简介

Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

存储结构类似:key:("value1", "value2", "value3")

常用命令

命令注释
sadd key value1 value2向集合添加一个或多个成员
scard key获取集合的成员数大小
sdiff key1 key2 key3返回第一个集合与其他集合之间的差异。
sdiffstore destination key1 key2返回给定所有集合的差集并存储在 destination 新key中
sinter key1 key2返回给定所有集合的交集
sinterstore destination key1 key2返回给定所有集合的交集并存储在 destination 新key中
sismember key value判断key的集合中是否存在value
smembers key返回key集合中所有的value
smove source destination value将 value 元素从 source的key 集合移动到 destination的key 集合中
spop key随机获取并移除key中的一个value
srandmember key count随机返回集合中count个value
srem key value1 value2移除集合中一个或多个value
sunion key1 key2返回所有给定集合的并集
sunionstore destination key1 key2所有给定集合的并集存储在 destination key集合中
SSCAN key cursor [MATCH pattern] [COUNT count]迭代集合中的元素

Zset(sorted set)类型

简介

Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

有序集合的成员是唯一的,但分数(score)却可以重复。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

存储结构类似:key:{score1:value1, score2:value2, score3:value3, }

常用命令

命令注释
zadd key score1 value1 score2 value2向有序集合添加一个或多个成员,或者更新已存在成员的分数
zcard key获取有序集合的成员数
zcount key min max计算在有序集合中指定区间分数的成员数
zincrby key increment value有序集合中对指定成员的分数加上增量 increment
zinterstore destination numkeys key [key ...]计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中
zlexcount key min max在有序集合中计算指定字典区间内成员数量
zrange key start stop [WITHSCORES]通过索引区间返回有序集合指定区间内的成员
zrangebylex key min max [LIMIT offset count]通过字典区间返回有序集合的成员
zrangebyscore key min max [WITHSCORES] [LIMIT]通过分数返回有序集合指定区间内的成员
zrank key value返回有序集合中指定成员的索引
zrem key value [value ...]移除有序集合中的一个或多个成员
zremrangebylex key min max移除有序集合中给定的字典区间的所有成员
zremrangebyrank key start end移除有序集合中给定的排名区间的所有成员
zremrangebyscore key min max移除有序集合中给定的分数区间的所有成员
zrevrange key start stop [WITHSCORES]返回有序集中指定区间内的成员,通过索引,分数从高到低
zrevrangebyscore key max min [WITHSCORES]返回有序集中指定分数区间内的成员,分数从高到低排序
zrevrank key value返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
zscore key value返回有序集中,成员的分数值
zunionstore destination numkeys key [key ...]计算给定的一个或多个有序集的并集,并存储在新的 key 中
zscan key cursor [MATCH pattern] [COUNT count]迭代有序集合中的元素(包括元素成员和元素分值)

IT 老哥

`一个在大厂做高级Java开发的程序猿`

 









原文转载:http://www.shaoqun.com/a/504722.html

跨境电商:https://www.ikjzd.com/

eori:https://www.ikjzd.com/w/499

孙琦:https://www.ikjzd.com/w/1638


前言(求点赞)jvm我们讲了两篇文章,为了不让大家学习疲劳,我们几个技术穿插着来讲,我们今天讲讲Redis的各种命令,这篇会把大家日常需要用到的命令全都列出来,满足你们的日常工作需求。redis五大数据类型redis键(key)常用命令命令注释keys*获取所有的keyselect0(库角标)选择第几个库movekey0(库角标)将当前的数据库key移动到某个数据库,目标库有,则不能移动flush
百思买:百思买
ifttt:ifttt
2020椰林沙滩大型动漫灯会倒数活动?深圳椰林沙滩元旦跨年:2020椰林沙滩大型动漫灯会倒数活动?深圳椰林沙滩元旦跨年
乳源云门峡漂流门票价格?云门峡漂流怎么样?:乳源云门峡漂流门票价格?云门峡漂流怎么样?
乐高星球大战五月重返马来西亚乐高主题公园有什么好玩的?:乐高星球大战五月重返马来西亚乐高主题公园有什么好玩的?

布隆过滤器详解,全网最全一篇

前言

我们之前讲了Redis的缓存雪崩、穿透、击穿。在文章里我们说了解决缓存穿透的办法之一,就是布隆过滤器,但是上次并没有讲如何使用布隆过滤器。

作为暖男的老哥,给你们补上,请叫我IT老暖男

什么是布隆过滤器

布隆过滤器(Bloom Filter),是1970年,由一个叫布隆的小伙子提出的,距今已经五十年了,和老哥一样老。

它实际上是一个很长的二进制向量和一系列随机映射函数,二进制大家应该都清楚,存储的数据不是0就是1,默认是0。

主要用于判断一个元素是否在一个集合中,0代表不存在某个数据,1代表存在某个数据。

懂了吗?作为暖男的老哥在给你们画张图来帮助理解:

布隆过滤器用途

  • 解决Redis缓存穿透(今天重点讲解)

  • 在爬虫时,对爬虫网址进行过滤,已经存在布隆中的网址,不在爬取。

  • 垃圾邮件过滤,对每一个发送邮件的地址进行判断是否在布隆的黑名单中,如果在就判断为垃圾邮件。

以上只是简单的用途举例,大家可以举一反三,灵活运用在工作中。

布隆过滤器原理

存入过程

布隆过滤器上面说了,就是一个二进制数据的集合。当一个数据加入这个集合时,经历如下洗礼(这里有缺点,下面会讲):

  • 通过K个哈希函数计算该数据,返回K个计算出的hash值

  • 这些K个hash值映射到对应的K个二进制的数组下标

  • 将K个下标对应的二进制数据改成1。

例如,第一个哈希函数返回x,第二个第三个哈希函数返回y与z,那么: X、Y、Z对应的二进制改成1。

如图所示:

查询过程

布隆过滤器主要作用就是查询一个数据,在不在这个二进制的集合中,查询过程如下:

  • 通过K个哈希函数计算该数据,对应计算出的K个hash值

  • 通过hash值找到对应的二进制的数组下标

  • 判断:如果存在一处位置的二进制数据是0,那么该数据不存在。如果都是1,该数据存在集合中。(这里有缺点,下面会讲)

删除过程

一般不能删除布隆过滤器里的数据,这是一个缺点之一,我们下面会分析。

布隆过滤器的优缺点

优点

  • 由于存储的是二进制数据,所以占用的空间很小

  • 它的插入和查询速度是非常快的,时间复杂度是O(K),可以联想一下HashMap的过程

  • 保密性很好,因为本身不存储任何原始数据,只有二进制数据

缺点

这就要回到我们上面所说的那些缺点了。

添加数据是通过计算数据的hash值,那么很有可能存在这种情况:两个不同的数据计算得到相同的hash值。

例如图中的"你好"和"hello",假如最终算出hash值相同,那么他们会将同一个下标的二进制数据改为1。

这个时候,你就不知道下标为2的二进制,到底是代表"你好"还是"hello"。

由此得出如下缺点:

一、存在误判

假如上面的图没有存"hello",只存了"你好",那么用"hello"来查询的时候,会判断"hello"存在集合中。

因为"你好"和"hello"的hash值是相同的,通过相同的hash值,找到的二进制数据也是一样的,都是1。

二、删除困难

到这里我不说大家应该也明白为什么吧,作为你们的暖男老哥,还是讲一下吧。

还是用上面的举例,因为"你好"和"hello"的hash值相同,对应的数组下标也是一样的。

这时候老哥想去删除"你好",将下标为2里的二进制数据,由1改成了0。

那么我们是不是连"hello"都一起删了呀。(0代表有这个数据,1代表没有这个数据)

到这里是不是对布隆过滤器已经明白了,都说了我是暖男。

实现布隆过滤器

有很多种实现方式,其中一种就是Guava提供的实现方式。

一、引入Guava pom配置

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>29.0-jre</version>
</dependency>
复制代码

二、代码实现

这里我们顺便测一下它的误判率。

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;

public class BloomFilterCase {

  /**
   * 预计要插入多少数据
   */
  private static int size = 1000000;

  /**
   * 期望的误判率
   */
  private static double fpp = 0.01;

  /**
   * 布隆过滤器
   */
  private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, fpp);


  public static void main(String[] args) {
    // 插入10万样本数据
    for (int i = 0; i < size; i++) {
      bloomFilter.put(i);
    }

    // 用另外十万测试数据,测试误判率
    int count = 0;
    for (int i = size; i < size + 100000; i++) {
      if (bloomFilter.mightContain(i)) {
        count++;
        System.out.println(i + "误判了");
      }
    }
    System.out.println("总共的误判数:" + count);
  }
}
复制代码

运行结果:

10万数据里有947个误判,约等于0.01%,也就是我们代码里设置的误判率:fpp = 0.01。

深入分析代码

核心BloomFilter.create方法

@VisibleForTesting
  static <T> BloomFilter<T> create(
      Funnel<? super T> funnel, long expectedInsertions, double fpp, Strategy strategy) {
    。。。。
}
复制代码

这里有四个参数:

  • funnel:数据类型(一般是调用Funnels工具类中的)

  • expectedInsertions:期望插入的值的个数

  • fpp:误判率(默认值为0.03)

  • strategy:哈希算法

我们重点讲一下fpp参数

fpp误判率

情景一:fpp = 0.01

  • 误判个数:947

  • 占内存大小:9585058位数

情景二:fpp = 0.03(默认参数)

  • 误判个数:3033

  • 占内存大小:7298440位数

情景总结

  • 误判率可以通过fpp参数进行调节

  • fpp越小,需要的内存空间就越大:0.01需要900多万位数,0.03需要700多万位数。

  • fpp越小,集合添加数据时,就需要更多的hash函数运算更多的hash值,去存储到对应的数组下标里。(忘了去看上面的布隆过滤存入数据的过程)

上面的numBits,表示存一百万个int类型数字,需要的位数为7298440,700多万位。理论上存一百万个数,一个int是4字节32位,需要481000000=3200万位。如果使用HashMap去存,按HashMap50%的存储效率,需要6400万位。可以看出BloomFilter的存储空间很小,只有HashMap的1/10左右

上面的numHashFunctions表示需要几个hash函数运算,去映射不同的下标存这些数字是否存在(0 or 1)。


 









原文转载:http://www.shaoqun.com/a/504707.html

跨境电商:https://www.ikjzd.com/

tenso:https://www.ikjzd.com/w/1552.html

prezi:https://www.ikjzd.com/w/1751


前言我们之前讲了Redis的缓存雪崩、穿透、击穿。在文章里我们说了解决缓存穿透的办法之一,就是布隆过滤器,但是上次并没有讲如何使用布隆过滤器。作为暖男的老哥,给你们补上,请叫我IT老暖男。什么是布隆过滤器布隆过滤器(BloomFilter),是1970年,由一个叫布隆的小伙子提出的,距今已经五十年了,和老哥一样老。它实际上是一个很长的二进制向量和一系列随机映射函数,二进制大家应该都清楚,存储的数据
焦点科技:焦点科技
prime day:prime day
亚马逊搜索排名规则:亚马逊搜索排名规则
白天去广州海珠湖公园还是海心沙好?:白天去广州海珠湖公园还是海心沙好?
Boux Avenue:Boux Avenue

注意!美国包裹量暴增,快递公司征收附加费,暂停大订单

注意!美国包裹量暴增,快递公司征收附加费,暂停大订单

每年圣诞购物旺季,美国的包裹量都会暴增,随之全国性寄递企业就跟着收取附加费,缓解成本压力,今年也不例外。

但不同之处在于,受新冠肺炎疫情影响,北美快递企业提前半年就展开了"寄递马拉松"拉锯战。据Supplychiandive网站报道,美国企业递送压力可能会延续到2021年。附加费加收的日期也将会被延长。

据《巴伦周刊》12月15日报道,由于受新冠肺炎疫情影响,美国联邦快递和联合包裹业务量激增,有时甚至会出现快递延误。

近年来,快递时效的提升拉高了消费者的期望,一周或者更长的等待时间会导致消费者的不满。某些零售商也会因此流失客源。因此,联邦快递和联合包裹开始限制揽收零售商包裹,以确保时效。

据MarketWatch报道,不久前,联合包裹就告知快递司机在"网络星期一"要选择性接单,避免延误,其中就包括12月初暂时拒接GAP和耐克等品牌的某些订单。

MarketWatch援引《华尔街日报》从联合包裹员工处得知的消息称,其他临时限制接单的大型零售客户还包括Hot Topic、New Egg和梅西百货等。

除了限制接单,联邦快递和联合包裹还在附加费方面增添了"新花样"。

Supplychaindive网站报道称,联邦快递为了应对持续业务压力,自今年6月开始加收附加费。12月第三周又公布了3项附加费,其中包括76美分的SmartPost轻小件服务附加费,从2021年1月18日生效,持续时间等待进一步通知。虽然76美分低于旺季附加费的1-2美元,但高于6月份公布的40美分的水平。其他附加费还包括针对超大尺寸包裹加收30美元,高于6月份的旺季附加费标准。

咨询公司LPF Spend Management创始人Nate Skiver认为,2021年如果市场环境与2020年相似,承运企业运能有限、送货上门需求旺盛、市场主体稀缺,这种附加费价格机制就将持续,其他快递企业也会有类似调价行为。

当压力传导至末端时,美国邮政也招架不住了。

此前8月份美国邮政公布,从10月18日至12月27日,美国国内商业包裹的季节性附加费标准为0.24-1.5美元,这对于整个旺季期间依赖美国邮政的小包裹商家影响尤其大。

其中,包裹退货服务原来起步价为3.05美元,其间涨价24美分;优先商务邮件原价为7.02美元,涨了40美分;优先商务快递邮件原价为22.75美元涨价1.5美元。

报道显示,除了临时附加费,美国邮政最近还公布了其他涨价内容。从2021年1月24日开始,各项运输服务价格均要上涨,幅度为1.2%-20%。尤其是优先邮件和一类包裹价格变动较大。即便如此,美国邮政2020年预计仍将亏损,亏损额高达76亿美元。


虽然美国邮政不会对燃油、送件上门和常规的周六快递服务收取附加费,不过对于在邮件处理系统内发现的超尺寸大件包裹要多收取100美元,以抑制邮件处理系统内经常出现大件的网购包裹。

专家认为,由于美国邮政提供的末端派送服务国内最低,涨价意味着美国的"免费快递服务"很快将成为历史。

今后大小零售商需要不断创新,节约成本,扩大快递服务选择,在全国性、区域性及第三方物流企业之间找到业务平衡点。分析认为,多元化寄递选择确实可以降低物流成本,提高寄递时效,且减少客户因对寄递服务的不满影响品牌美誉度。

因此,零售商要尽量避免季节性附加费以及可能超过业务量上限带来的高收费,同时也要确保满足客户寄递需求,留住客户。研究称,56%的美国被调查者表示如果寄递体验差就不会选择相应零售商。

相应的,国际快递寄到美国的派送服务也受到延误影响。


来源:威速易供应链平台

文章来源:https://www.ikjzd.com/home/139036

跨境电商:https://www.ikjzd.com/

张洁:https://www.ikjzd.com/w/1663

凹凸曼:https://www.ikjzd.com/w/1392

旺店通:https://www.ikjzd.com/w/2390

注意!美国包裹量暴增,快递公司征收附加费,暂停大订单

每年圣诞购物旺季,美国的包裹量都会暴增,随之全国性寄递企业就跟着收取附加费,缓解成本压力,今年也不例外。

​在亚马逊开店必做的几件事—让流量和转化率同时提高

​在亚马逊开店必做的几件事—让流量和转化率同时提高

一、你不得不知的亚马逊特色

亚马逊中国的第三方平台,与国内其他平台有很大的不同,兹将亚马逊的四大特色说明如下:

1、重推荐 轻广告

相较硬广告和活动,亚马逊基于后台数据的关联推荐及排行推荐是转换率最高的推广方式,但该方式是系统自动根据用户的购买记录和买家好评推荐的,故增加选(新)品与优化后台数据、推荐买家写好评非常重要

2、重商品详情 轻客服咨询

亚马逊鼓励客户自助购物,故不设置在线客服。您需要将产品情页写得尽可能丰富,以帮助客户尽快做出购买决定,避免因信息不全,而导致客户放弃购买。

3、重产品轻店铺

亚马逊强调产品而非店铺、卖家,在亚马逊页面上买家搜索产品,不会出现店铺,是以统一的陈列标准展现产品。

4、重视客户反馈:

亚马逊有两套评价体系。1)商品评论:商品评论会呈现在产品详情页,直接影响转化率。2)买家反馈:主要是客户对于您提供的服务质量的评级。会显示在卖家详情页。这个评级会决定您是否有资格赢得单一产品页面的购物车按钮及排名。

二、在亚马逊开店必做的几件事--让流量和转化率同时提高

1、开店必做之一、优化产品图片

»说明:图片的质量无论对产品搜索结果页面的效果(影响点击率)还是对产品详情页面的转化购买(影响转换率)都会有至关重要的作用

图片编辑技巧:


2、开店必做之二、使用亚马逊物流

官方数据证明:使用FBA销量可提高4-5倍

说明:

1)影响搜索排名:使用亚马逊物流是影响搜索排名靠前的关键因素之一,使用亚马逊物流的产品会被优先排序;

2)影响转化率:亚马逊物流支持货到付款,70%以上的亚马逊客户习惯货到付款;

使用亚马逊物流注意事项


3、开店必做之三、提高卖家信用

通过提高卖家绩效和优化买家评价体系

»说明:

1)影响搜索排名:商品好评多,卖家绩效高是影响搜索排名靠前的关键因素之一;

2)影响转化率:在详细页面中,好评多的产品转化率高;

卖家绩效注意事项

  • 卖家需要多关注自己的卖家绩效,具有杰出绩效的卖家可通过其商品旁边所显示的反馈评级来使自己脱颖而出。绩效差的卖家除了销量会大大降低外,还很可能被警告,暂停营业,甚至关店的处罚。

  • 主要包括三部分:卖家指标反馈(即顾客评分) 亚马逊商城交易保障赔付(即顾客索赔)

卖家绩效之卖家指标

  • 卖家指标主要包括订单缺陷率、取消率、迟发率、联系回复时间和违反政策这五部分

  • 订单缺陷率是绩效中最重要的指标,如果低于1%将没有购物车。由负面反馈率(顾客差评)和亚马逊商城交易保障索赔率(顾客索赔)两部分组成。

  • 请务必每天查看后台绩效-业绩通知的任何通知,如果收到要主动采取相应行动。

卖家绩效之管理客户反馈

亚马逊有两套评价体系:其一是买家反馈,对应后台-绩效中的买家"反馈",买家只有在购买此商品后才能对该商品的卖家进行反馈评级。

不求人建议大家定期监控自己的绩效。了解自己所有绩效指标的相关数据,卖家可以方便地看到自己是否达到了我们的目标。保证自己账号安全!



来源:AMZ跨境不求人

文章来源:https://www.ikjzd.com/home/139052

跨境电商:https://www.ikjzd.com/

vava:https://www.ikjzd.com/w/2780

blibli:https://www.ikjzd.com/w/1676

myshow:https://www.ikjzd.com/w/2235

​在亚马逊开店必做的几件事—让流量和转化率同时提高

最近不少朋友问我,现在亚马逊还可以不可以,不求人肯定的回答:可以。但是现在绝对不是红利期,想要通过亚马逊短期致富的可能不大。所以今天就就借此好好聊聊不求人眼中的亚马逊。

亚马逊站内广告如何做?

亚马逊站内广告如何做?

亚马逊站内广告在亚马逊运营中是绕不开,但很多卖家转化很差,不尽如人意。那就看大卖们是怎么做的!

五大广告怎么组合投放呢?

自动、手动跑流量 

自动和手动广告,我们怎么样投?

第一,广告分为两个部分,自动和广泛。这两个广告组,自动去跑流量,广泛去不计成本的把这些流量流到Listing里面去。

换句话,自动广告的词跑出来之后,这些词流到我们的广泛广告里面去,不计成本    

这里的不计成本是指,在不计较Acos和转化率的情况下,自动广告里面跑出来的词,只能在广泛里面能够继续去跑,出单。

第二,广泛里面的词是自动广告里面跑出来一次,在广泛里面走一遍之后,接着把广泛里面的词往词组里面去放,投放词组时要考虑广告成本。

在词组广告中,一定要把Acos和转化率数据优化得漂亮,这时要考虑PCTR(曝光点击)的成本

接着把这些词投放到词组广告,一段时间之后数据表现不错的,再投放手动精准。

这些词在手动精准中,控制好Acos和转化率,最好所有的词都能控制到50%以下,不能超过50%。

这些词在手动精准里面跑了一段时间,对应关键词的自然排名在第三页,第四页第二页等等。

表现特别好的词会在第一页。这时我们要做的是利用手动精准的广告,继续控制Acos和转化率。

如果Acos是40%,怎么办呢?

通过我们的操作,比如点击一次成交两单,一个点击广告费一美金,成交一单销售额17美金。

如果我们成交两单,销售额34美金,这样就把Acos降低了,包括转化率也一样,点击一次成交一次。

这时,转化率也会提高。对于在手动精准里面的词,排名在第二,第三,第四页的,稍微去推动一下Acos和转化率,它的排名立马往上跳。

出了几单之后跳到首页。首页那些排名靠后的,也稍微操作几单,排名会往前面跳。  

以上操作核心标准就是Acos和转化率

但是我想提醒一句,我们在做广告的时候,有两点必须要注意

第一,我们的四组广告,自动、广泛、词组、精准这四个广告并不是同时开的

顺序是,(1)自动,(2)广泛,(3)词组,(4)手动,(5)手动精准

接着是四个广告是放五个活动,而不是无个广告放一个活动,五个组,这样也是不行的。

第二,我们在做广告的时候,表现不好的词及时移除,会影响其他词的表现,所以一定要剔除。

类目广告

第二个部分:类目广告。

类目广告投放,看产品。红海产品的类目广告的效果可能不好。但蓝海产品的类目广告可能效果会稍微好点。 

那类目广告怎么做?

第一,广告投放到所在的类目的类目广告。在类目里面打你产品的类目广告。比如Listingg类目排名在300名左右的,类目广投了之后,你的广告位置就排到了四十名或者五十名。

第二,广告投放到其他类目的类目广告。也就是你在投放类目广告的时候,去换另外一个类目去投放,而不是换Listing类目。

这时,你同时占有占两个类目排名的流量,也挺好。但,前提是Listing显示的自然类目排名相对来比较靠前,你已经没有必要去抢这个自然类目的流量。

这时,自然类目流量靠前了,你去打另外一个类目的广告流量,把那个类目的流量看能不能抢一抢,做一做,这样就没问题。

--END--



来源:闯盟跨境电商

文章来源:https://www.ikjzd.com/home/139033

跨境电商:https://www.ikjzd.com/

五洲会:https://www.ikjzd.com/w/1068

prime day:https://www.ikjzd.com/w/131

友家速递:https://www.ikjzd.com/w/1341

亚马逊站内广告如何做?

亚马逊站内广告在亚马逊运营中是绕不开,但很多卖家转化很差,不尽如人意。那就看大卖们是怎么做的!五大广告怎么组合投放呢?自动、手动跑流量自动和手动广告,我们怎么样投?第一,广告分为两个部分,自动和广泛。这两个广告组,自动去跑流量,广泛去不计成本的把这些流量流到Listing里面去。

kubernetes中有状态应用的优雅缩容

将有状态的应用程序部署到Kubernetes是棘手的。 StatefulSet使它变得容易得多,但是它们仍然不能解决所有问题。最大的挑战之一是如何缩小StatefulSet而不将数据留在断开连接的PersistentVolume成为孤立对象上。在这篇博客中,我将描述该问题和两种可能的解决方案。

通过StatefulSet创建的每个Pod都有自己的PersistentVolumeClaim(PVC)和PersistentVolume(PV)。当按一个副本按比例缩小StatefulSet的大小时,其Pod之一将终止,但关联的PersistentVolumeClaim和绑定到其的PersistentVolume保持不变。在随后扩大规模时,它们会重新连接到Pod。

imgScaling a StatefulSet

现在,想象一下使用StatefulSet部署一个有状态的应用程序,其数据在其pod中进行分区。每个实例仅保存和处理一部分数据。当您缩小有状态应用的规模时,其中一个实例将终止,其数据应重新分配到其余的Pod。如果您不重新分配数据,则在再次进行扩展之前,它仍然不可访问。

imgRedistributing data on scale-down

在正常关机期间重新分发数据

您可能会想:"既然Kubernetes支持Pod正常关闭的机制,那么Pod是否可以在关闭过程中简单地将其数据重新分配给其他实例呢?"事实上,它不能。为什么不这样做有两个原因:

  • Pod(或更确切地说,其容器)可能会收到除缩容以外的其他原因的终止信号。容器中运行的应用程序不知道为什么终止该程序,因此不知道是否要清空数据。
  • 即使该应用程序可以区分是缩容还是由于其他原因而终止,它也需要保证即使经过数小时或数天也可以完成关闭程序。 Kubernetes不提供该保证。如果应用程序进程在关闭过程中死掉,它将不会重新启动,因此也就没有机会完全分发数据。

因此,相信在正常关闭期间Pod能够重新分发(或以其他方式处理其所有数据)并不是一个好主意,并且会导致系统非常脆弱。

使用 tear-down 容器?

如果您不是Kubernetes的新手,那么你很可能知道什么是初始化容器。它们在容器的主要容器之前运行,并且必须在主要容器启动之前全部完成。

如果我们有tear-down容器(类似于init容器),但是在Pod的主容器终止后又会运行,该怎么办?他们可以在我们的有状态Pod中执行数据重新分发吗?

img

假设tear-down容器能够确定Pod是否由于缩容而终止。并假设Kubernetes(更具体地说是Kubelet)将确保tear-down容器成功完成(通过在每次返回非零退出代码时重新启动它)。如果这两个假设都成立,我们将拥有一种机制,可确保有状态的容器始终能够按比例缩小规模重新分配其数据。

但是?

可悲的是,当tear-down容器本身发生瞬态错误,并且一次或多次重新启动容器最终使它成功完成时,像上述的tear-down容器机制将只处理那些情况。但是,在tear-down过程中托管Pod的集群节点死掉的那些不幸时刻又如何呢?显然,该过程无法完成,因此无法访问数据。

现在很明显,我们不应该在Pod关闭时执行数据重新分配。相反,我们应该创建一个新的Pod(可能安排在一个完全不同的集群节点上)以执行重新分发过程。

这为我们带来了以下解决方案:

缩小StatefulSet时,必须创建一个新的容器并将其绑定到孤立的PersistentVolumeClaim。我们称其为"drain pod",因为它的工作是将数据重新分发到其他地方(或以其他方式处理)。Pod必须有权访问孤立的数据,并且可以使用它做任何想做的事情。由于每个应用程序的重新分发程序差异很大,因此新的容器应该是完全可配置的-用户应该能够在drain Pod内运行他们想要的任何容器。

StatefulSet Drain Controller

由于StatefulSet控制器当前尚不提供此功能,因此我们可以实现一个额外的控制器,其唯一目的是处理StatefulSet缩容。我最近实现了这种控制器的概念验证。您可以在GitHub上找到源代码:

luksa/statefulset-scaledown-controllergithub.com图标

下面我们解释一下它是如何工作的。

在将控制器部署到Kubernetes集群后,您只需在StatefulSet清单中添加注释,即可将drain容器模板添加到任何StatefulSet中。这是一个例子:

apiVersion: apps/v1kind: StatefulSetmetadata: name: datastore annotations: statefulsets.kubernetes.io/drainer-pod-template: |  {  "metadata": {   "labels": {   "app": "datastore-drainer"   }  },  "spec": {   "containers": [   {    "name": "drainer",    "image": "my-drain-container",    "volumeMounts": [    {     "name": "data",     "mountPath": "/var/data"    }    ]   }   ]  }  }spec: ...

该模板与StatefulSet中的主要Pod模板没有太大区别,只不过它是通过注释定义的。您可以像平常一样部署和扩展StatefulSet。

当控制器检测到按比例缩小了StatefulSet时,它将根据指定的模板创建新的drain容器,并确保将其绑定到PersistentVolumeClaim,该PersistentVolumeClaim先前已绑定至因按比例缩小而删除的有状态容器。

Drain容器获得与已删除的有状态容器相同的身份(即名称和主机名)。这样做有两个原因:

  • 一些有状态的应用程序需要稳定的身份-这也可能在数据重新分发过程中适用。
  • 如果在执行drain过程时再次扩容StatefulSet,则这将阻止StatefulSet控制器创建重复的容器并将其附加到同一PVC。

如果drain pod或其主机节点崩溃,则drain pod将重新安排到另一个节点上,在该节点上可以重试/恢复其操作。Drain pod完成后, Pod和PVC将被删除。备份StatefulSet时,将创建一个新的PVC。

示例

首先部署drain控制器:

$ kubectl apply -f https://raw.githubusercontent.com/luksa/statefulset-drain-controller/master/artifacts/cluster-scoped.yaml

接着部署示例StatefulSet:

$ kubectl apply -f https://raw.githubusercontent.com/luksa/statefulset-drain-controller/master/example/statefulset.yaml

这将运行三个有状态的Pod。将StatefulSet缩小为两个时,您会看到其中一个Pod开始终止。然后,删除Pod后,drain控制器将立即创建一个具有相同名称的新drain Pod:

$ kubectl scale statefulset datastore --replicas 2statefulset.apps/datastore scaled$ kubectl get poNAME   READY  STATUS  RESTARTS AGEdatastore-0 1/1  Running  0   3mdatastore-1 1/1  Running  0   2mdatastore-2 1/1  Terminating 0   49s$ kubectl get poNAME   READY  STATUS RESTARTS AGEdatastore-0 1/1  Running 0   3mdatastore-1 1/1  Running 0   3mdatastore-2 1/1  Running 0   5s <-- the drain pod

当drain pod 完成其工作时,控制器将其删除并删除PVC:

$ kubectl get poNAME   READY  STATUS RESTARTS AGEdatastore-0 1/1  Running 0   3mdatastore-1 1/1  Running 0   3m$ kubectl get pvcNAME    STATUS VOLUME    CAPACITY ...data-datastore-0 Bound  pvc-57224b8f-... 1Mi  ...data-datastore-1 Bound  pvc-5acaf078-... 1Mi  ...

控制器的另一个好处是它可以释放PersistentVolume,因为它不再受PersistentVolumeClaim约束。如果您的集群在云环境中运行,则可以降低存储成本。

总结

请记住,这仅是概念验证。要成为StatefulSet缩容问题的正确解决方案,需要进行大量工作和测试。理想情况下,Kubernetes StatefulSet控制器本身将支持这样的运行drain容器,而不是需要一个与原始控制器竞争的附加控制器(当您缩容并立即再次扩容时)。

通过将此功能直接集成到Kubernetes中,可以在StatefulSet规范中用常规字段替换注释,因此它将具有模板,volumeClaimTemplatesrainePodTemplate,与使用注释相比,一切都变得更好了。









原文转载:http://www.shaoqun.com/a/504685.html

跨境电商:https://www.ikjzd.com/

宝付:https://www.ikjzd.com/w/539

华翰物流:https://www.ikjzd.com/w/1799


将有状态的应用程序部署到Kubernetes是棘手的。StatefulSet使它变得容易得多,但是它们仍然不能解决所有问题。最大的挑战之一是如何缩小StatefulSet而不将数据留在断开连接的PersistentVolume成为孤立对象上。在这篇博客中,我将描述该问题和两种可能的解决方案。通过StatefulSet创建的每个Pod都有自己的PersistentVolumeClaim(PVC)和P
米兰网:米兰网
一淘比价网:一淘比价网
母亲节这一习俗是怎么来的?:母亲节这一习俗是怎么来的?
长期稳定的获取Review,你还有很多可以做!:长期稳定的获取Review,你还有很多可以做!
口述:老公被小三甩了我还怎么接受他(2/2):口述:老公被小三甩了我还怎么接受他(2/2)

JavaScript(二)

属性、样式操作

改变元素样式的方式:外部样式表、内部样式表、行内样式。

获取元素的显示样式

获取节点的方式:

通过id获取:document.getElementById()
通过选择器来获取:document.querySelector(),document.querySelectorAll()
通过class名字获取:document.getElementsByClassName()
通过标签名获取:document.getElementsByTagName()
通过name获取:document.getElementsByName()

用classList来操作类名

添加类名: .classList.add()  移除类名: .classList.remove()
切换类名(有则移除,没有则添加): .classList.toggle()


let oWrap = document.getElementById("wrap"); //不标准的写法 // oWrap.style = "width: 300px"; //style 这个合法的标签属性很特殊 console.log( oWrap.style ); oWrap.style.width = "300px"; oWrap.style.height = "200px"; oWrap.style.backgroundColor = "red";//样式操作let oWrap = document.getElementById("wrap"); oWrap.onclick = function(){  // oWrap.style.width = "500px";  //在事件函数里面,可以用 this来代替oWrap  this.style.width = "500px"; };//变相操作样式let oWrap = document.getElementById("wrap"); oWrap.onclick = function(){  //添加名字,点击时,更换名字生成样式  this.className = "fly"; };

 










原文转载:http://www.shaoqun.com/a/504677.html

跨境电商:https://www.ikjzd.com/

cicpa:https://www.ikjzd.com/w/1375

笨鸟:https://www.ikjzd.com/w/2713


属性、样式操作改变元素样式的方式:外部样式表、内部样式表、行内样式。获取元素的显示样式获取节点的方式:通过id获取:document.getElementById()通过选择器来获取:document.querySelector(),document.querySelectorAll()通过class名字获取:document.getElementsByClassName()通过标签名获取:doc
跨境通电子商务:跨境通电子商务
ryder:ryder
巴西旅游娱乐 感受浪漫情人节 - :巴西旅游娱乐 感受浪漫情人节 -
泰国的泰式古法按摩有何作用?:泰国的泰式古法按摩有何作用?
Amazon Marketplace Professional Services Program:Amazon Marketplace Professional Services Program

在社交媒体平台上应用模因的四大原因

可能有卖家会问模因是什么?模因Meme是由进化生物学家Richard Dawkins在1976年创造的一个术语,用于描述想法如何复制变异和进化,是一种承载共同想法或趋势以吸引目标群体的方式。随着时间的流逝,不同的群体会采用模因并对其进行调整使其成为自己的模因。


简单来说,模因就是通过交流圈子中每个人都能理解的东西来建立社区也就是我们俗称的"梗"。那么,卖家在内容营销中使用模因,又能有什么收获呢?


模因很容易创建


首先,创建模因不需要研究关键字或者花功夫制作精美的图像,通过模因生成器,卖家可以过滤流行的模因或上传图像来搜索模因图像,在选择图像和添加文本之后,卖家就可以下载模因并在社交平台上进行使用了。


模因提高参与度


模因非常有感染力,可以帮助人们通过幽默的方式进行交流。比如说,订阅服务BarkBox 的Instagram帐户就主打只有爱犬人士才知道的狗的有趣小怪癖,这些爱犬人士才能理解的主题使他们感到自己是专属团体的一部分。


模因富有娱乐


用户关注社交媒体的娱乐性,而卖家制作的简单有趣的模因可以与受众联系起来,即使这些模因与自己的品牌并不沾边,但获得的分享和点赞都可能使自己的品牌在用户心中占得一席之地。


模因展现品牌个性


通过社交媒体账户,卖家可以增强当前的品牌个性或创建一个全新的品牌个性,比如说,有着上百年历史的MoonPie在社交媒体上打造了一个更年轻有趣的形象。


综上,模因已经成为我们生活中的一部分,网络上的字、词、短语等都可以成为模因,这也是卖家可以利用的有效资源。但是,卖家在应用模因的时候要考虑到一点,模因往往是热闹的和新鲜的。


2020年是要过去了,但营销永无止境,各位卖家也要在自己的营销计划中不断创新,以期实现更好的营销效果。




原文转载:http://www.shaoqun.com/a/504666.html

跨境电商:https://www.ikjzd.com/

瀚霖:https://www.ikjzd.com/w/2345

ideal:https://www.ikjzd.com/w/2286


可能有卖家会问模因是什么?模因(Meme)是由进化生物学家RichardDawkins在1976年创造的一个术语,用于描述想法如何复制、变异和进化,是一种承载共同想法或趋势以吸引目标群体的方式。随着时间的流逝,不同的群体会采用模因并对其进行调整使其成为自己的模因。简单来说,模因就是通过交流圈子中每个人都能理解的东西来建立社区,也就是我们俗称的"梗"。那么,卖家在内容营销中使用模因,又能有什么收获呢
商标抢注:商标抢注
lithium:lithium
封城、停航、旅行禁令...中国经历的一切正在海外上演:封城、停航、旅行禁令...中国经历的一切正在海外上演
PriceYak:PriceYak
六一放假安排,2020六一儿童节放假安排:六一放假安排,2020六一儿童节放假安排

@欧洲站卖家,英国脱欧过渡期结束在即,这些新规即将生效!

@欧洲站卖家,英国脱欧过渡期结束在即,这些新规即将生效!

英国脱欧过渡期将于12月31日结束,自2021年1月1日起将会有一批新规生效,卖家需提前做好应对!


知识产权相关变化

自2021年1月1日起,欧盟商标/外观专利在英国无效,卖家不能以此举报英国站listing侵权。品牌所有者应在英国和欧盟的知识产权局拥有单独的商标/外观专利。

亚马逊品牌变化:

1已使用欧盟商标进行亚马逊品牌注册

过渡期结束前完成注册的欧盟商标,将会由英国知识产权局转换成相应的英国商标。

英国知识产权局转换完成后,亚马逊会自动将转换后的商标添加到Amazon Brand Registry账户中,卖家无需进行操作。

2已使用欧盟商标进行亚马逊品牌注册,但不希望自动添加英国商标

需选择手动向亚马逊品牌注册账户添加任何其他商标(包括任何现有的英国商标),并且自行发送电子邮件至brand-registry-contact-us@amazon.com 选择不予参加。

3有现成的英国商标,希望自行添加到亚马逊品牌注册账户

  • 在https://brandregistry.amazon.co.uk上登录您的账户

  • 点击"品牌注册"控制面板上的"支持"

  • 点击"联系品牌支持",选择"更新您的品牌资料"

  • 点击"添加其他商标"

  • 填写提供的表格

4
有现成的欧盟商标,但还未进行亚马逊品牌注册

①如果您在2020年12月31日之前使用欧盟商标完成注册,亚马逊将自动添加对应的英国商标。

②如果您在2020年12月31日之后添加新的欧盟商标,则您需要自行添加相应的英国商标。

新的增值税法规

自2021年1月1日起,英国市场将施行一套新的增值税法规,以确保来自英国境外的货物与已经在英国境内的货物承担相同的增值税。

主要变化:

英国境外向英国卖家配送

▲托运价值低于 £15 的商品,亚马逊将根据英国税务机关要求必须代收代缴适用的增值税

▲托运商品的价值不超过 £135,亚马逊将根据英国税务机关要求必须代收代缴适用的增值税

▲托运商品的价值超过 £135,则和目前一样,您仍需自行缴纳增值税和所有进口关税

英国境内库存向英国买家配送

如果您通过英国境内的库存向英国买家配送商品,且您公司的成立地在英国境外,则必须由亚马逊代收代缴适用的增值税。这对在英国境内使用亚马逊物流的卖家和使用第三方配送方式的卖家均适用。

英国境外库存向英国企业及机构买家配送

如果您从英国境外向英国买家配送商品,且该买家在英国登记了增值税(企业及机构买家),则亚马逊无需代收和代缴增值税。已登记增值税的买家可通过其增值税申报单自行申报英国增值税。

卖家如何应对增值税法规变更?

①确保卖家平台账户的详细信息为最新,查阅和更新公司注册地址以及实际的"发货地址"的信息。

②发布在亚马逊商城中的市场价始终包含增值税

新的商品或贴标法规

一、UKCA取代CE标志

英国政府宣布自2021年1月1日开始,UKCA标志将正式开启使用。CE标志将仅适用于欧盟,产品销售到英国,必须加贴UKCA标志!



满足以下所有条件的产品,需在2021年1月1日后立即使用UKCA标志:

  • 用于英国市场

  • 涉及UKCA标记的立法的保护

  • 强制性第三方合格评定

  • 合格性评估由英国合格性评估机构进行,您尚未在2021年1月1日之前将合格性评估文件从英国机构转移到欧盟认可的机构

需要注意的是,UKCA标志的生效日期是2021年1月1日。在这日期之前,已经进入或在途的商品不受此制度影响。在途证明包括订单、发票、物流单等。

二、英国合规负责人

今年6月份,亚马逊发邮件通知欧洲站卖家:自2021年7月起,卖家想要继续在欧盟销售带有CE标志的产品,就需要任命一名负责人,负责卖家在欧盟的品牌/产品。

所谓的负责人,就是欧洲站卖家常说的"欧代"。现有欧盟合规负责人到2020年12月31日后将无法同时涵盖英国与欧盟。

也就是说,投放至欧盟国家/地区的商品需要具备CE标志及欧盟合规负责人,若同时销售到英国,则需另外具备UKCA标志及英国合规负责人。

三、英国专属的合规声明(UK DoC)

英国合规声明所需的信息,与当前欧盟合规声明要求的信息大体相同(具体商品可能因申请法规的不同而稍有差异)。

以上就是英国脱欧过渡期结束后生效的新规,欧洲站卖家一定要知道并提前做好应对措施。



来源:积特知识产权

文章来源:https://www.ikjzd.com/home/139037

跨境电商:https://www.ikjzd.com/

宝付:https://www.ikjzd.com/w/539

贝贝网:https://www.ikjzd.com/w/1321

吉祥邮:https://www.ikjzd.com/w/1565

@欧洲站卖家,英国脱欧过渡期结束在即,这些新规即将生效!

英国脱欧过渡期将于12月31日结束,自2021年1月1日起将会有一批新规生效,卖家需提前做好应对!知识产权相关变化自2021年1月1日起,欧盟商标/外观专利在英国无效,卖家不能以此举报英国站listing侵权。品牌所有者应在英国和欧盟的知识产权局拥有单独的商标/外观专利。亚马逊品

JS编写的科学计算器

最近半个月编写了一个JS+CSS+HTML的网页计算器,从最初的具有简陋界面的简单计算器改版到最终具有科学/标准计算器转换功能并且界面非常友好的计算器,收获良多!总的来说,代码简单,通俗易读,下面贴上代码,供前端新手学习!欢迎提出宝贵意见,不吝指正!

 

 

 HTML代码(代码中仅仅是计算器界面内容布局):

<html><head>	<title>计算器</title> <link href="style.css" rel="stylesheet" type="text/css"/> <script src="script.js"></script> </head> <body> <div id="calculator">	<a href="http://write.blog.csdn.net/postlist" id='record'>计Sweet Smile</a>	<div >		<textarea type="text" id="result0" οnfοcus="this.blur();"></textarea>		<textarea type="text" id="result" οnfοcus="this.blur();"></textarea>	</div> 	<div>		<section >   <!--包含按钮的一个长形区域-->		 <div οnclick="styleChange()">					 <!--包含按钮的一个较小长形区域-->		 <input type="checkbox"/>		 <label>科学标准</label>					<!--按钮底部的灰色滑动区-->		 </div>		</section>	</div> 	<!--标准计算器布局--> 	<div id="rows" >	<div >		<button id="bt1" οnclick="zero()">C</button>		<button id="bt2" οnclick="back()">DEL</button>		<button id="bt3" οnclick="divide()">÷</button>		<button id="bt4" οnclick="times()">×</button>	</div>	<div >		<button id="bt5" οnclick="num(7)">7</button>		<button id="bt6" οnclick="num(8)">8</button>		<button id="bt7" οnclick="num(9)">9</button>		<button id="bt8" οnclick="plus()">+</button>	</div>	<div >		<button id="bt9" οnclick="num(4)">4</button>		<button id="bt10" οnclick="num(5)">5</button>		<button id="bt11" οnclick="num(6)">6</button>		<button id="bt12" οnclick="minus()">-</button>	</div> 	<div id="below">		<div id="left">			<div >				<button id="bt13" οnclick="num(1)">1</button>				<button id="bt14" οnclick="num(2)">2</button>				<button id="bt15" οnclick="num(3)">3</button>			</div>			<div >				<button id="bt16" οnclick="num(0)">0</button>				<button id="bt17" οnclick="dot()">.</button>			</div>		</div>		<div id="right">			<button id="bt18" οnclick="equal()">=</button>		</div>	</div> 	</div> 	<!--科学计算器布局-->	<div id="sci" >		<div >				<button id="bt21" οnclick="zero()">C</button>				<button id="bt22" οnclick="back()">DEL</button>				<button id="bt23" οnclick="pow1()">^</button>				<button id="bt24" οnclick="num('π')">π</button>				<button id="bt25" οnclick="pow2()">√</button>		</div>		<div >				<button id="bt26" οnclick="sin()">sin</button>				<button id="bt27" οnclick="num('(')">(</button>				<button id="bt28" οnclick="num(')')">)</button>				<button id="bt29" οnclick="divide1()">1/X</button>				<button id="bt30" οnclick="divide()">÷</button>		</div>		<div >				<button id="bt31" οnclick="cos()">cos</button>				<button id="bt32" οnclick="num(7)">7</button>				<button id="bt33" οnclick="num(8)">8</button>				<button id="bt34" οnclick="num(9)">9</button>				<button id="bt35" οnclick="times()">×</button>		</div>		<div >				<button id="bt36" οnclick="tan()">tan</button>				<button id="bt37" οnclick="num(4)">4</button>				<button id="bt38" οnclick="num(5)">5</button>				<button id="bt39" οnclick="num(6)">6</button>				<button id="bt40" οnclick="minus()">-</button>		</div>		<div >				<button id="bt41" οnclick="ln()">ln</button>				<button id="bt42" οnclick="num(1)">1</button>				<button id="bt43" οnclick="num(2)">2</button>				<button id="bt44" οnclick="num(3)">3</button>				<button id="bt45" οnclick="plus()">+</button>		</div>		<div >				<button id="bt46" οnclick="log()">log</button>				<button id="bt47" οnclick="num(0)">0</button>				<button id="bt48" οnclick="dot()">.</button>				<button id="bt49" οnclick="quyu()">%</button>				<button id="bt50" οnclick="equal()">=</button>		</div> 	</div> 	</div> </body></html>

下面是JS代码(代码语句都是非常简单的基础语法):

//改进: 定义一个变量记录"="的输入与否而不必每输入数字时都要检索一遍文本框内容 var status=0;	//标记所输入的是数字还是运算符号var calcu=0;	//标记所要执行的方法是哪一个 /*数字、括号及PI的输入*/function num(x){	var str0=document.getElementById('result0').value;	var str=document.getElementById('result').value;	if(str0.indexOf("=")>0){		document.getElementById('result0').value='';		document.getElementById('result').value='0';		str=document.getElementById('result').value;	}	if(str=="0")		str=''; 	str+=String(x); 	document.getElementById('result').value=str; 	status=0;}//输入. (未做是否包含"."的判断)function dot(){	var str0=document.getElementById('result0').value;	var str=document.getElementById('result').value;	if(str0.indexOf("=")>0){		document.getElementById('result0').value='';		document.getElementById('result').value='0';		str=document.getElementById('result').value;	}	str=str+'.'; 	document.getElementById('result').value=str;} /*三角函数以及'1/'计算*/function sin(){	calcu=1;	cal();}function cos(){	calcu=2;	cal();}function tan(){	calcu=3;	cal();}function divide1(){	calcu=4;	cal();}function ln(){	calcu=5;	cal();}function log(){	calcu=6;	cal();}function cal(){	var str0=document.getElementById('result0').value;	var str=document.getElementById('result').value;	if(str0.indexOf("=")>0){		document.getElementById('result0').value='';		document.getElementById('result').value='0';		str=document.getElementById('result').value;	}	if(str=="0")		str='';	switch(calcu){           case 1: str+=String("sin(");break;      case 2: str+=String("cos(");break;      case 3: str+=String("tan(");break;   case 4: str+=String("1/");break;  case 5: str+=String("ln(");break;  case 6: str+=String("log(");break; } 	document.getElementById('result').value=str; 	status=1;} /* ^、√以及%的输入 */function pow1(){	calcu=1;	powS();}function pow2(){	calcu=2;	powS();}function quyu(){	calcu=3;	powS();}function powS(){	if(status == 1)		return;	var strpow0=document.getElementById('result0').value;	var strpow=document.getElementById('result').value;	if(strpow0.indexOf("=")>0){		document.getElementById('result0').value='';		/*document.getElementById('result').value='0';*/		strpow=document.getElementById('result').value;	}	switch(calcu){		case 1: strpow+=String('^'); 			 break;		case 2: if(strpow=='0')			 		strpow="√";			 	else{			 		strpow+=String('√');			 	}			 break;		case 3: strpow+=String("%");				break;	}	document.getElementById('result').value=strpow;	status=1;} /* +-×÷ 运算 */function plus(){	calcu=1;	calculate();}function times(){	calcu=2;	calculate();}function divide(){	calcu=3;	calculate();		}function calculate(){	if(status==1)		return;	var str0=document.getElementById('result0').value;	var str=document.getElementById('result').value;	if(str0.indexOf("=")>0 ){		document.getElementById('result0').value='';		/*document.getElementById('result').value='0';*/		str=document.getElementById('result').value;	}	if(str=='')		str='0';	switch(calcu){		case 1: str+='+';break;		case 2: str+='×';break;		case 3: str+='÷';break;	} 	document.getElementById('result').value=str; 	status=1;}function minus(){	var str0=document.getElementById('result0').value;	var str=document.getElementById('result').value;	if(str0.indexOf("=")>0){		document.getElementById('result0').value='';		/*document.getElementById('result').value='-';*/		str=document.getElementById('result').value+'-';	} 	else 		str+='-'; 	document.getElementById('result').value=str;} //显示屏字符串为空function zero(){	document.getElementById('result0').value=""; 	document.getElementById('result').value="0";} //显示屏字符串减去最后一个字符function back(){	var str0=document.getElementById('result0').value;	var str=document.getElementById('result').value;	if(str0.indexOf("=")>0 || str=='')		return;	var str1=str.substr(0,(str.length)-1) 	document.getElementById('result').value=str1;} //获取当前显示屏字符,判断所包含运算符,并做相关运算。function equal(){	var str0=document.getElementById('result').value;	if(str0=="")		return;	var str=str0.replace(/×/g,'*');		//用正则表达式进行全部替换	str=str.replace(/÷/g,'/');	str=str.replace(/π/g,'Math.PI');	if(str.indexOf("sin")>=0){		str=str.replace(/sin/g,'Math.round(Math.sin');		str+='*1000000)/1000000'; 		document.getElementById('result0').value=str0.concat("=");		document.getElementById('result').value=eval(str);			}	else if(str.indexOf("cos")>=0){		str=str.replace(/cos/g,'Math.round(Math.cos');		str+='*1000000)/1000000';		document.getElementById('result0').value=str0.concat("=");		document.getElementById('result').value=eval(str);	}	else if(str.indexOf("tan")>=0){		str=str.replace(/tan/g,'Math.round(Math.tan');		str+='*1000000)/1000000';		document.getElementById('result0').value=str0.concat("=");		document.getElementById('result').value=eval(str);	}	else if(str.indexOf("^")>=0){		var pos=str0.indexOf('^');		var pow1=str0.substring(0,pos);		var pow2=str0.substring(pos+1,str0.length+1);		result=Math.pow(pow1, pow2);		document.getElementById('result0').value=str0.concat("=");		document.getElementById('result').value=eval(result);	}	else if(str.indexOf("√")>=0){		var pos=str0.indexOf('√');		var pow1=str0.substring(0,pos);		var pow2=str0.substring(pos+1,str0.length+1);		if(pow1==''){			result=Math.pow(pow2,0.5);			document.getElementById('result0').value=str0.concat("=");			document.getElementById('result').value=eval(result);		}		else{			result=Math.pow(pow2, 1/pow1);			document.getElementById('result0').value=str0.concat("=");			document.getElementById('result').value=eval(result);		}	}	else if(str.indexOf("ln")>=0){		var str=str0.replace(/ln/g,'Math.round(Math.log');		str+='*1000000)/1000000';		document.getElementById('result0').value=str0.concat("=");		document.getElementById('result').value=eval(str);	}	else if(str.indexOf("log")>=0){		var str=str0.replace(/log/g,'Math.log');		str+= '/Math.log(10)';		document.getElementById('result0').value=str0.concat("=");		document.getElementById('result').value=eval(str);	}	else{		result=(eval(str));		document.getElementById('result0').value=str0.concat("=");		document.getElementById('result').value=result;	}	var a=document.getElementById('result').value;	if(a=="Infinity")		document.getElementById('result').value='∞';	else if(a=="-Infinity")		document.getElementById('result').value='-∞';}function styleChange(){	if(document.getElementById('rows').style.display=='inline'){		document.getElementById('rows').style.display='none';		document.getElementById('sci').style.display='inline';	}	else if(document.getElementById('rows').style.display=='none'){		document.getElementById('rows').style.display='inline';		document.getElementById('sci').style.display='none';	}}

下面是CSS代码(其中按钮效果部分参考了纯CSS滑动按钮特效代码):

body { 	font-size:24px; 	font-family:Arial, Georgia, "Times New Roman", Times, serif; 	color:#555; 		text-align:center; 			background-color:#555; 		}body div{	align:center;	margin-top:5px;	} #calculator{	align:center;	width:350px; height:550px;	margin:10px auto;	border:#fff 2px solid;		overflow:hidden;  	background-color:#f2f2f2; 	 } .rescult{	align:center;	padding:10px 5px 0px 5px;}#result,#result0{	width:300px;	height:40px;	font-size:35px;	text-align:right;	direction:ltr; 	border:#C0C0C0;	overflow:hidden;  	background-color:#C0C0C0;	word-wrap : normal;	}#result0{ font-size:25px;}section { float: left; width:100px; padding: 0px 200px 10px 20px; height: 50px;} .checkbox { position: relative; display: inline-block; } .checkbox label { font-size:20px; text-align: center; padding-top: 5px; width: 90px; height: 30px; position: relative; display: inline-block; border-radius: 46px;   -webkit-transition: 0.4s;  transition: 0.4s;}.checkbox label:after {  content: ''; position: absolute; padding-top: 20px; width: 45px; height: 20px; border-radius: 40%; left: 0;     top: -5px; z-index: 2;   background: #f2f2f2;  box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);  -webkit-transition: 0.4s; transition: 0.4s;}.checkbox input { position: absolute; left: 0; top: 0; width: 100%;  height: 100%; z-index: 5;   opacity: 0;  cursor: pointer; } .checkbox input:hover + label:after { box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.2), 0 3px 8px 0 rgba(0, 0, 0, 0.2);}.checkbox input:checked + label:after { left: 45px;      

}.model-1 .checkbox input:checked + label { background:#ccc ;   }.model-1 .checkbox input:checked + label:after { background:#f2f2f2;   } #rows{ 	align:center;	padding:0 3px; }#below{	margin-top:0px;	margin-left:25px;	margin-bottom: 30px;	width:300px;}#left{	margin-top:0px;	float:left;}#right{	margin-top:10px;	float:right;}.row1,.row2,.row3,#below{	align:center;	}.row3{	margin-bottom: 0px;}#bt1,#bt2,#bt3,#bt4,#bt5,#bt6,#bt7,#bt8,#bt9,#bt10,#bt11,#bt12,#bt13,#bt14,#bt15,#bt16,#bt17,#bt18{	font-size:18px;	width:70px;	height:70px;	background-color:#eaeaea; 	cursor:pointer; }#bt16{	width:145px;}#bt18{	height:140px;}#sci{ display:none;}#sci button{ font-size:18px; width:55px; height:55px; background-color:#eaeaea; cursor:pointer; }#record{ float:right; font-size:15px; color:#555;}#record:hover{ color:red;}

转载于:https://blog.csdn.net/sweet___smile/article/details/50417211









原文转载:http://www.shaoqun.com/a/504648.html

跨境电商:https://www.ikjzd.com/

houzz:https://www.ikjzd.com/w/236

跨境通电子商务网站:https://www.ikjzd.com/w/1329


最近半个月编写了一个JS+CSS+HTML的网页计算器,从最初的具有简陋界面的简单计算器改版到最终具有科学/标准计算器转换功能并且界面非常友好的计算器,收获良多!总的来说,代码简单,通俗易读,下面贴上代码,供前端新手学习!欢迎提出宝贵意见,不吝指正!HTML代码(代码中仅仅是计算器界面内容布局):<html><head> <title>计算器</title
笨鸟海淘:笨鸟海淘
Sunrate:Sunrate
四川赏桃花:出树香梢几树花 :四川赏桃花:出树香梢几树花
排雷!广告投放的这些坑,你都踩过吗?:排雷!广告投放的这些坑,你都踩过吗?
武侯祠对联和祖孙父子兄弟君臣联 :武侯祠对联和祖孙父子兄弟君臣联

Wednesday, December 30, 2020

冬天这3个部位最怕冻,女人一定要护好

核心提示:寒冷的冬天一定要做好保暖工作,尤其是一些重点部位,女性朋友一定要护好。

对于很多爱美的妹纸来说,寒冷不可怕,"丑"才是原罪。即使在寒冷的冬天,她们依然选择"风度"而放弃"温度",殊不知,你的"放弃"带来的可不仅仅是冷,还可能带走你的健康。


39健康提醒各位女性朋友,冬天一定要做好保暖工作,尤其是下面这几个重点部位。

1.脖子

预防疾病:肌膜炎

寒冷的冬天也要秀出天鹅颈,还要顺便秀出新买的项链。但是,骨科医生表示,不注意颈部保暖,有可能诱发肌筋膜炎。长时间把颈部肌肉暴露在寒冷的空气中,因"热胀冷缩",所以颈部肌肉就会收缩,引起颈部炎症。另外,脖子上也有很多穴位,如大椎穴,如保暖不当,寒气就会入侵身体,影响颈背部的活动,从而导致颈椎病。

专家建议,天气转凉,颈部保暖万万不可忽视,平时可以穿高领毛衣或戴上围巾,防寒保暖的同时还可以促进颈部血液循环。

2.腰腹

预防疾病:妇科病

低腰裤能完美的展现女性的身材,让女性显得更性感。但是低腰裤的危害也是极其大的,尤其是在冬天。低腰裤的暴露部位主要是肚脐、腹部、腰部,肚脐是人体内最容易受风寒的部位,长期将肚脐暴露在外,就会引起腹泻、腹痛等症状,严重者还会导致妇科疾病。

再说到腰部,"腰为肾之府",腰部受寒,就会影响肾功能,肾气不足,阳气就会衰弱,人就会感出现冷、无力、饮食少,大便呈糖稀状。

3.脚踝

预防疾病:关节炎

不知道从哪一年开始,九分裤开始流行,即使冬天也不例外,经常看到很多年轻妹纸露着脚踝在寒风中瑟瑟发抖。但是在医生看来,这样的穿着等于是把你的关节往死路上推。

我们的脚踝部位分布着淋巴管、血管、神经等近十个重要的组织,脚一直被称为人体的第二心脏,现在是冬季,风有时比较大,如果经常把脚踝露出来,不仅会引发踝关节炎,还会使抗病能力下降而导致感冒。


脚是人整个身体的支撑,脚踝是腿和脚的连结部位,一旦受守,会导致踝关节部位血液循环变差,引发疾病。

专家表示,女性本来的体质就容易贫血,再说寒从脚起,好好护脚能避免手脚冰凉的现象。如果脚受冷,就会加重冰凉的现象,还会影响身体的血液循环,从而导致正常的生理活动受限。平时爱漂亮无可厚非,但是冷天还是不要拿自己的身体去冒险。

专家建议,无论在哪个季节,女性都不应该长期穿低腰裤,应该好好保护腰腹部,以免引起身体问题。


原文转载:http://health.shaoqun.com/a/139611.html

跨境电商:https://www.ikjzd.com/

马莎:https://www.ikjzd.com/w/2385

mil:https://www.ikjzd.com/w/1285


核心提示:寒冷的冬天一定要做好保暖工作,尤其是一些重点部位,女性朋友一定要护好。 对于很多爱美的妹纸来说,寒冷不可怕,"丑"才是原罪。即使在寒冷的冬天,她们依然选择"风度"而放弃"温度",殊不知,你的"放弃"带来的可不仅仅是冷,还可能带走你的健康。39健康提醒各位女性朋友,冬天一定要做好保暖工作,尤其是下面这几个重点部位。1.脖子预防疾病:肌膜炎寒冷的冬天也要秀出天鹅颈,还要顺便秀出新买的项链。但
zen cart:zen cart
环球b2b:环球b2b
口述:老公一夜冲锋5次掩盖出轨真相老公真相一夜:口述:老公一夜冲锋5次掩盖出轨真相老公真相一夜
网红营销时代,大数据取胜:网红营销时代,大数据取胜
厦门的消费水平高吗?:厦门的消费水平高吗?

Zookeeper笔记分享

Zookeeper采用zap协议来保证数据的一致性
常见的数据一致性协议采用raft协议
 
参数解读:
  tickTime=2000:心跳包发送间隔时长
  initLimit=10:leader与follower之间初始化时的最大超时时间,10X2000(理解为第一次连接时的超时时长)
  syncLimit=5:leader与follower之间正常通讯超时时长,5X2000(集群正常启动之后的通讯超时时长)
  clientPort=2181:客户端访问服务端的端口号
选举机制:
半数机制,推荐奇数台服务器
先选自己,如果不行就优先选择myid最大的,先入为主
 
 

Zookeeper简介

  ZooKeeper 是一种分布式协调服务,用于管理大型主机。在分布式环境中协调和管理服务是一个复杂的过程。ZooKeeper 通过其简单的架构和 API 解决了这个问题。ZooKeeper 允许开发人员专注于核心应用程序逻辑,而不必担心应用程序的分布式特性。

分布式应用

  分布式应用可以在给定时间(同时)在网络中的多个系统上运行,通过协调它们以快速有效的方式完成特定任务。通常来说,对于复杂而耗时的任务,非分布式应用(运行在单个系统中)需要几个小时才能完成,而分布式应用通过使用所有系统涉及的计算能力可以在几分钟内完成。
通过将分布式应用配置为在更多系统上运行,可以进一步减少完成任务的时间。分布式应用正在运行的一组系统称为集群,而在集群中运行的每台机器被称为节点。
  分布式应用有两部分, Server(服务器) 和 Client(客户端) 应用程序。服务器应用程序实际上是分布式的,并具有通用接口,以便客户端可以连接到集群中的任何服务器并获得相同的结果。 客户端应用程序是与分布式应用进行交互的工具。
 
  ZooKeeper 是一个分布式协调服务的开源框架。主要用来解决分布式集群中应用系统的一致性的问题,例如怎样避免同时操作同一数据造成脏读的问题。ZooKeeper 本质上是一个分布式的小文件存储系统。提供基于类似于文件系统的目录树方式的数据存储,并且可以对树种 的节点进行有效管理。从而来维护和监控你存储的数据的状态变化。将通过监控这些数据状态的变化,从而可以达到基于数据的集群管理。诸如:统一命名服务(dubbo)、分布式配置管理(solr的配置集中管理)、分布式消息队列(sub/pub)、分布式锁、分布式协调等功能。
 

Zookeeper 架构图


Zookeeper集群角色介绍

  • Leader: ZooKeeper 集群工作的核心 事务请求(写操作)的唯一调度和处理者,保证集群事务处理的顺序性;集群内部各个服务的调度者。 对于 create,setData,delete 等有写操作的请求,则需要统一转发给 leader 处理,leader 需要决定编号、执行操作,这个过程称为一个事务。

  • Follower: 处理客户端非事务(读操作)请求 转发事务请求给 Leader 参与集群 leader 选举投票2n-1台可以做集群投票 此外,针对访问量比较大的 zookeeper 集群,还可以新增观察者角色

  • Observer: 观察者角色,观察ZooKeeper集群的最新状态变化并将这些状态同步过来,其对于非事务请求可以进行独立处理,对于事务请求,则会转发给Leader服务器处理 不会参与任何形式的投票只提供服务,通常用于在不影响集群事务处理能力的前提下提升集群的非事务处理能力 通常来说就是增加并发的请求


ZooKeeper当中的主从与主备:

  • 主从:主节点少,从节点多,主节点分配任务,从节点具体执行任务

  • 主备:主节点与备份节点,主要用于解决我们主机节点挂掉以后,如何选出来一个新的主节点的问题,保证我们的主节点不会宕机

  • 很多时候,主从与主备没有太明显的分界线,很多时候都是一起出现

Zookeeper的特性

  1. 全局数据的一致:每个 server 保存一份相同的数据副本,client 无论链接到哪个 server,展示的数据都是一致的
  2. 可靠性:如果消息被其中一台服务器接受,那么将被所有的服务器接受
  3. 顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息 a 在消息 b 前发布,则在所有 server 上消息 a 在消息 b 前被发布,偏序是指如果以个消息 b 在消息 a 后被同一个发送者发布,a 必须将排在 b 前面
  4. 数据更新原子性:一次数据更新要么成功,要么失败,不存在中间状态
  5. 实时性:ZooKeeper 保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息

分布式应用的优点

  • 可靠性 - 单个或几个系统的故障不会使整个系统出现故障。
  • 可扩展性 - 可以在需要时增加性能,通过添加更多机器,在应用程序配置中进行微小的更改,而不会有停机时间。
  • 透明性 - 隐藏系统的复杂性,并将其显示为单个实体/应用程序。

分布式应用的挑战

  • 竞争条件 - 两个或多个机器尝试执行特定任务,实际上只需在任意给定时间由单个机器完成。例如,共享资源只能在任意给定时间由单个机器修改。
  • 死锁 - 两个或多个操作等待彼此无限期完成。
  • 不一致 - 数据的部分失败。

什么是Apache ZooKeeper?

  Apache ZooKeeper是由集群(节点组)使用的一种服务,用于在自身之间协调,并通过稳健的同步技术维护共享数据。ZooKeeper本身是一个分布式应用程序,为写入分布式应用程序提供服务。
ZooKeeper提供的常见服务如下 :
  • 命名服务 - 按名称标识集群中的节点。它类似于DNS,但仅对于节点。
  • 配置管理 - 加入节点的最近的和最新的系统配置信息。
  • 集群管理 - 实时地在集群和节点状态中加入/离开节点。
  • 选举算法 - 选举一个节点作为协调目的的leader。
  • 锁定和同步服务 - 在修改数据的同时锁定数据。此机制可帮助你在连接其他分布式应用程序(如Apache HBase)时进行自动故障恢复。
  • 高度可靠的数据注册表 - 即使在一个或几个节点关闭时也可以获得数据。

  分布式应用程序提供了很多好处,但它们也抛出了一些复杂和难以解决的挑战。ZooKeeper框架提供了一个完整的机制来克服所有的挑战。竞争条件和死锁使用故障安全同步方法进行处理。另一个主要缺点是数据的不一致性,ZooKeeper使用原子性解析。
ZooKeeper的好处

以下是使用ZooKeeper的好处:

  • 简单的分布式协调过程
  • 同步 - 服务器进程之间的相互排斥和协作。此过程有助于Apache HBase进行配置管理。
  • 有序的消息
  • 序列化 - 根据特定规则对数据进行编码。确保应用程序运行一致。这种方法可以在MapReduce中用来协调队列以执行运行的线程。
  • 可靠性
  • 原子性 - 数据转移完全成功或完全失败,但没有事务是部分的。

 
 
Zookeeper = 树形节点znode文件系统+通知系统
 
每一个znode节点默认存储1MB的数据
1、一个领导者与多个跟随者构成的集群
2、集群中过半节点存活,zookeeper集群就能正常服务
3、全局数据一致:每一个server都会同步当前最新的数据副本,client无论连接到那一台server数据都是一致的
4、更新请求顺序执行,来自同一个Client的更新请求按其发送顺序依次执行(针对每一个客户端的更新请求顺序执行)
5、实时性
 

Zookeeper的应用场景

  • 分布式锁
  • 集群选主
  • 统一命名服务
  • 统一配置管理(监听配置)
  • 携程配置中心 阿波罗
  • 统一集群管理(监听集群中节点变化)
  • 服务器节点动态上下线
  • 负载均衡

 
节点类型

 

 

zkCli指令 

zkCli.sh --server host:port:连接到指定的服务端
创建节点必须要设置数据
create (path | znode) data :创建持久节点
create -s (path | znode) data :创建持久顺序编号目录节点
create -e (path | znode) data :创建短暂节点
create -e -s (path | znode) data :创建短暂顺序编号目录节点
get znode:可以获取节点内存储的数据和源数据
get znode watch:注册某个节点的监听服务
set znode newData:设置节点的值
ls znode:查看节点下的子节点
ls znode watch:注册某个节点所有子节点的监听服务
ls2 znode:查看节点的元数据
delete znode:删除节点
rmr znode:递归删除节点
stat znode:查看节点状态

 

zookeeper就两种集群部署方式:单机部署和集群部署
 
zk来最适合进行选主,和分布式锁(串行化方式)
 
ZK写操作

 

任何一个分布式系统都要满足分区容错性 P,因为不能因为集群中某一的节点宕机,就导致整个集群不具备容错性而导致不能再正常提供服务
 
 
什么是AP模型?简单的说就是集群中一般以上节点宕机之后集群仍然可以提供服务,但其实它还涉及到一点,就是服务端每一次的请求都能收到响应,而ZK必须满足一半以上节点存活才能提供服务,而且在选举Leader期间也是不对外提供服务的,由此推断ZK输入CP模型
 
 
 
1 eureka AP
eureka 保证了可用性,实现最终一致性。
Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或时如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性),其中说明了,eureka是不满足强一致性,但还是会保证最终一致性
2 zookeeper CP
zookeeper在选举leader时,会停止服务,直到选举成功之后才会再次对外提供服务,这个时候就说明了服务不可用,但是在选举成功之后,因为一主多从的结构,zookeeper在这时还是一个高可用注册中心,只是在优先保证一致性的前提下,zookeeper才会顾及到可用性
  • C(一致性):所有的节点上的数据时刻保持同步
  • A(可用性):每个请求都能接受到一个响应,无论响应成功或失败
  • P(分区容错):系统应该能持续提供服务,即使系统内部有消息丢失(分区)

高可用、数据一致是很多系统设计的目标,但是分区又是不可避免的事情:
  • CA without P:如果不要求P(不允许分区),则C(强一致性)和A(可用性)是可以保证的。但其实分区不是你想不想的问题,而是始终会存在,因此CA的系统更多的是允许分区后各子系统依然保持CA。
  • CP without A:如果不要求A(可用),相当于每个请求都需要在Server之间强一致,而P(分区)会导致同步时间无限延长,如此CP也是可以保证的。很多传统的数据库分布式事务都属于这种模式。
  • AP wihtout C:要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。现在众多的NoSQL都属于此类。

Zookeeper怎么保证数据的一致性?

  ZooKeeper写数据的机制是客户端把写请求发送到leader节点上(如果发送的是follower节点,follower节点会把军请求转发到leader节点), leader节点会把数据通过proposal请求发送到所有节点(包括自己),所有的节点接受到数据以后都会写到自己到本地磁盘上面,写好了以后会发送一个ack请求给leader,leader只要接受到过半的节点发送ack响应回来,就会发送commit消息给各个节点,各个节点就会把消息放入到内存中(放内存是为了保证高性能),该消息就会用户可见了。那么这个时候,如果ZooKeeper要想保证数据一致性,就需要考虑如下两个情况∶
 
 
情况一∶leader执行commit了,还没来得及给follower发送commit的时候,leader宕机了,这个时候如何保证消息一致性?
 
解决︰当leader宕机以后,ZzooKeeper会选举出来新的Leader,新的leader后动以后要到磁盘上面去检查是否存在没有comit到消息,如果存在,就继续检查看其他follower有没有对这条消息进行了commit,如果有过半节点对这条消息进行了ack,但是没有commit,那么新对1eader要完成commit对操作。
 
情况二︰客户端把消息写到leader了,但是leader还没发送proposal消息给其他节点,这个时候leader宕机了,leader宕机后恢复的时候此消息又该如何处理?
 
解决∶客户端把消息写到leader了,但是leader还没发送portal消息给其他节点,这个时候leader宕机了,这个时候对于用户来说,这条消息是写失败的。假设过了一段时间以后leader节点又恢复了,不过这个时候角色就变为了follower了,它在检查自己磁盘的时候会发现自己有一条消息没有进行commit,此时就会检测消息的编号,消息是有编号的,由高32位和低32位组成,高32位是用来体现是否发生过leader切换的,低32位就是展示消息的顺序的。这个时候当前的节点就会根据高32位知道目前leader已经切换过了,所以就把当前的消息删除,然后从新的leader同步数据,这样保证了数据一致性。
Zookeeper的Observer节点
对应一个ZooKeeper集群,我们可能有多个客户端,客户端能任意连接其中一台ZzooKeeper节点,但是所有的客户端都只能往leader节点上面去写数据,所有的客宁端能从所有的节点上面读取数据。如果有客户端连接的是follower节点,然后往follower上发送了写数据的请求,这个时候follower就会把这个写请求转发给1eader节点处理。leader接受到写请求就会往其他节点(包括自己)同步数据,如果过半的节点接受到消息后发送回来ack消息,那么leader节点就对这条消息进行commit,commit后该消息就对用户可见了。因为需要过半的节点发送ack后,l1eader才对消息进行comnit,这个时候会有一个问题,如果集群越大,那么等待过半节点发送回来ack消息这个过程就需要越久,也就是说节点越多虽然会增加集群的读性能,但是会影响到集事的写性能,所以我们一般建议ZooKeeper的集群规模在3到5个节点左右。为了解决这个问题,后来的Zookeeper中增加了一个observer 的角色,这个节点不参与投票,只是负责同步数据。比如我们leader写数据需要过半的节点发送ack响应,这个observer节点是不参与过半的数量统计的。它只是负责从leader同步数据,然后提供给客户端读取,所以引入这个角色目的就是为了增加集群读的性能,然后不影响集群的写性能。用户搭建集群的时候可以自己设置该角色。









原文转载:http://www.shaoqun.com/a/504561.html

跨境电商:https://www.ikjzd.com/

wario:https://www.ikjzd.com/w/887

刘军:https://www.ikjzd.com/w/1835


Zookeeper采用zap协议来保证数据的一致性常见的数据一致性协议采用raft协议参数解读:  tickTime=2000:心跳包发送间隔时长  initLimit=10:leader与follower之间初始化时的最大超时时间,10X2000(理解为第一次连接时的超时时长)  syncLimit=5:leader与follower之间正常通讯超时时长,5X2000(集群正常启动之后的通讯超时
刘军:刘军
新蛋:新蛋
广州到长津冰雪大世界怎么走?广州长津冰雪大世界自驾车路线?:广州到长津冰雪大世界怎么走?广州长津冰雪大世界自驾车路线?
口述:一见钟情 我和闺蜜的老公缠绵了一夜:口述:一见钟情 我和闺蜜的老公缠绵了一夜
口述:妻子和情人我该选哪个(2/2):口述:妻子和情人我该选哪个(2/2)